Страниц: [1] 2 3 ... 6
  Печать  
Автор Тема: long double  (Прочитано 38157 раз)
Dukales
Jr. Member
**
Offline Offline

Сообщений: 64


Просмотр профиля
« : Октября 26, 2009, 12:36:17 am »

И, вообще-то, "%f" требует дабла.
не требует. требует float.
lf - double == long float.
Lf - long double.
Записан

Это предложение содержит двенадцать слов, двадцать шесть слогов и семьдесят три буквы
oder
Гость
« Ответ #1 : Октября 26, 2009, 12:47:23 am »

Рекомендую обратиться к документации.
Например
http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/lib_ref/p/printf.html

f, F
Convert an argument of type double into a decimal notation in the form [-]ddd.ddd with the number of digits after the decimal point being equal to the precision specification. The leading sign appears (subject to the format control flags) only if the argument is negative.
The precision is used as the number of digits following the decimal-point character. If you don't specify the precision, a default precision of six is used. If the precision is 0, the decimal-point character is suppressed; otherwise, at least one digit is produced before the decimal-point character. The value is rounded to the appropriate number of digits.

An argument of type double that represents infinity or NaN is converted to [-]inf or [-]nan. The F specifier produces [-]INF or [-]NAN.

Поймете так или перевести?
В любом случае, ключевые слова выделил жирным.
Записан
Dukales
Jr. Member
**
Offline Offline

Сообщений: 64


Просмотр профиля
« Ответ #2 : Октября 26, 2009, 07:11:22 am »

я думал формат тоже стандартизирован для языка. А где тогда переносимость?
Записан

Это предложение содержит двенадцать слов, двадцать шесть слогов и семьдесят три буквы
oder
Гость
« Ответ #3 : Октября 26, 2009, 01:07:13 pm »

А MSVC тоже требует double, к примеру. Так что, это, скорее, у Вас система непереносимая. Wink
Записан
Dukales
Jr. Member
**
Offline Offline

Сообщений: 64


Просмотр профиля
« Ответ #4 : Октября 27, 2009, 01:52:27 am »

А MSVC тоже требует double, к примеру. Так что, это, скорее, у Вас система непереносимая. Wink
тогда где же универсальнсоть? нужно поддерживать все форматы. Ведь это "в железе", и нечего опасаться сделать спецификаторы для всех форматов. Или уж тогда имеет смысл делать для самого "широкого" из них - для long double - один спецификатор и параметры приводить к нему. Получается я ограничен в переводе из long double в текст?
Записан

Это предложение содержит двенадцать слов, двадцать шесть слогов и семьдесят три буквы
oder
Гость
« Ответ #5 : Октября 27, 2009, 02:02:42 am »

На большинстве нормальных платформ long double равен double. Стандарт на операции с плавающей запятой оперирует 8-байтными и 4-байтными действительными типами, которые при рассчётах внутри FPU приводятся к 80 битам для избежания потери точности.
Никакого long double в стандарте нет. Это всё от лукавого, который не знает, где бы ещё впихнуть этот 'long'.
Тоесть, есть, кончно, стандарт на вычисления с большей точностью, но это уже совсем другой стандарт.
Записан
Dukales
Jr. Member
**
Offline Offline

Сообщений: 64


Просмотр профиля
« Ответ #6 : Октября 27, 2009, 03:00:23 am »

...которые при рассчётах внутри FPU приводятся к 80 битам для избежания потери точности.
фраза лишена смысла
Записан

Это предложение содержит двенадцать слов, двадцать шесть слогов и семьдесят три буквы
Dukales
Jr. Member
**
Offline Offline

Сообщений: 64


Просмотр профиля
« Ответ #7 : Октября 27, 2009, 03:25:10 am »

В книге Страуструпа есть long double (ну это конечно не стандарт, но в "4.5 Типы с плавающей точкой" упоминается о нём).
Вообще, конечно, "от лукавого" здесь ничего нет. Есть сущности материальные - FPU (если говорить об x86) с его реальным устройством, его реальной поддержкой всех форматов (float, double, long double), а есть сущности, которые должны присутствовать в языке, чтобы использовать аппаратные возможности. Например, long long int имеет право на существование, так как аппаратно поддерживается. И dqword - тоже прямо как union не через typedef, а встроенный в язык. Раз C - язык более близкий к машине, то не такие уж это и фантазии. Вот что пишет Страуструп: "Предполагается, что компьютер имеет байты для хранения символов, слова для хранения целых чисел и выполнения арифметических операций с ними, нечто, подходящее для операций с плавающей точкой, а так же адреса для обращения к этим сущностям. Фундаментальные типы в C++ совместно с указателями и массивами предоставляют программисту понятия машинного уровня, но в форме, достаточно независимой от реализации.". Единственное, что "от лукавого", так это то, что расширенная точность аппаратно реализована в 80 битах, а не в 96 (мб я ошибаюсь).
Если аппаратная платформа не поддерживает long double (tbyte), то и будет он синонимом double в компиляторе под эту платформу.
« Последнее редактирование: Октября 27, 2009, 03:32:58 am от Dukales » Записан

Это предложение содержит двенадцать слов, двадцать шесть слогов и семьдесят три буквы
oder
Гость
« Ответ #8 : Октября 27, 2009, 02:18:39 pm »

Не собираюсь ни с кем спорить. Мне за это денег не плотят.
Записан
Evgeniy
Jr. Member
**
Offline Offline

Сообщений: 73


Просмотр профиля
« Ответ #9 : Октября 27, 2009, 04:31:03 pm »

Вот что пишет Страуструп...
Ура новому пророку! Вот и дождались: еще один Заратустра появился и мы его счастливые современники!... Как бы выиграли его тексты, если бы он поменьше философствовал!
Интересный тренд наблюдается в программистской (а может не только?) литературе: от четкого изложения идей, задач и решений к занудному мутному умствованию вокруг да около каких-то смутных ощущений. Впечатление такое, что, с одной стороны, авторы изо всех сил раздувают объем (раз эдак в 10) для увеличения гонорара, а, с другой - не слишком хорошо понимают то о чем пишут - "Кто ясно мыслит - тот ясно излагает".

Прошу простить за офтоп, но достало уже это низкопоклонство перед монстроклепателями...
Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #10 : Октября 27, 2009, 09:58:19 pm »

На большинстве нормальных платформ long double равен double. Стандарт на операции с плавающей запятой оперирует 8-байтными и 4-байтными действительными типами, которые при рассчётах внутри FPU приводятся к 80 битам для избежания потери точности.
Никакого long double в стандарте нет. Это всё от лукавого, который не знает, где бы ещё впихнуть этот 'long'.
Тоесть, есть, кончно, стандарт на вычисления с большей точностью, но это уже совсем другой стандарт.

Есть long double и в С и в С++ стандартах.
Записан

oder
Гость
« Ответ #11 : Октября 27, 2009, 10:22:34 pm »

Есть long double и в С и в С++ стандартах.

Да я знаю, что есть! Только, попоробуй найди, где он поддерживается! Разве что на каких-то там 64-битных Sparc-ах, кажется. Интелы, вроде, старались-старались и отказались (но я не в курсе последних новинок - признаюсь честно). А так, стандарт - абстракция, которой не существует в природе.

P.S. Я имел ввиду стандарт IEEE-какой-то-там на операции с числами с плавающей точкой.
« Последнее редактирование: Октября 27, 2009, 10:24:27 pm от oder » Записан
lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #12 : Октября 28, 2009, 11:16:38 am »

Есть long double и в С и в С++ стандартах.

Да я знаю, что есть! Только, попоробуй найди, где он поддерживается! Разве что на каких-то там 64-битных Sparc-ах, кажется. Интелы, вроде, старались-старались и отказались (но я не в курсе последних новинок - признаюсь честно). А так, стандарт - абстракция, которой не существует в природе.

P.S. Я имел ввиду стандарт IEEE-какой-то-там на операции с числами с плавающей точкой.

80 bit IEEE 754, раздел Extended precision

Поддерживался старыми компиляторами до выхода SSE2 процессоров. Borland C/C++ 3.x, 4.x, 5.x поддерживал long double как 10 байт в памяти - это 100%. GCC старые 2.9x.xx поддерживали long double точно так же.

Intel не отказывалась от 80 bit IEEE extended precision, сейчас компиляторы используют SSE2 инструкции для работы с floating point, а там максимум 64 бита (double), потому что SSE2 быстрее даже на одиночных операциях. Естественно, что производителям компиляторов было проще зарубить 80 бит long double, чтобы не было проблем с совместимостью библиотек использующих x87 FPU и библиотек, которые собраны с использованием SSE2 FPU. Везде одинаковый размер и одинаковое поведение, но разный результат.

x87 FPU инструкции FLD/FSTP работают с 32, 64 и 80 бит float для сохранения и загрузки данных из памяти в стек и наоборот.
Записан

lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #13 : Октября 28, 2009, 11:42:57 am »

Borland C/C++ 3.1 for DOS: sizeof(long double)=10
Borland C/C++ 5.5 for Win32: sizeof(long double)=10
GCC 3.4.4 for CygWin: sizeof(long double)=12 (это dword align влияет, а так обычный 80 bit precision)
GCC 2.95.3 for QNX 6.3.2: sizeof(long double)=12
GCC 3.3.5 for QNX 6.3.2: sizeof(long double)=12
Visual Studio 2005: sizeof(long double)=8
Visual Studio 2008: sizeof(long double)=8

Больше под рукой нет ничего проинсталенного, чтобы не менят винты на машине, но думаю, что и этого хватит.
« Последнее редактирование: Октября 28, 2009, 11:52:31 am от lestat » Записан

lestat
QOR.Moderator
*****
Offline Offline

Сообщений: 985


I don't trust anything


Просмотр профиля WWW
« Ответ #14 : Октября 28, 2009, 11:50:16 am »

Ну и напоследок программка и выхлоп gcc:

Код:
#include <stdio.h>

int main()
{
    long double a=5;
    long double b=2;
    long double c=0;

    c=a+b;

    printf("%Lf\n", c);
    return 0;
}

Ассемблерный выхлоп:

Код:
.file "a.cc"
.version "01.01"
gcc2_compiled.:
.section .rodata
.LC2:
.string "%Lf\n"
.align 16
.LC0:
.long 0x0
.long 0xa0000000
.long 0x4001
.align 16
.LC1:
.long 0x0
.long 0x80000000
.long 0x4000
.text
.align 4
.globl main
.type main,@function
main:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp,%ebp
.LCFI1:
subl $56,%esp
.LCFI2:
fldt .LC0
fstpt -16(%ebp)
fldt .LC1
fstpt -32(%ebp)
movl $0,-48(%ebp)
movl $0,-44(%ebp)
movl $0,-40(%ebp)
fldt -16(%ebp)
fldt -32(%ebp)
faddp %st,%st(1)
fstpt -48(%ebp)
fldt -48(%ebp)
subl $12,%esp
fstpt (%esp)
pushl $.LC2
.LCFI3:
call printf
addl $16,%esp
xorl %eax,%eax
jmp .L38
xorl %eax,%eax
jmp .L38
.align 4
.L38:
leave
ret
.LFE1:
.Lfe1:
.size main,.Lfe1-main

.section .eh_frame,"aw",@progbits
__FRAME_BEGIN__:
.4byte .LLCIE1
.LSCIE1:
.4byte 0x0
.byte 0x1
.byte 0x0
.byte 0x1
.byte 0x7c
.byte 0x8
.byte 0xc
.byte 0x4
.byte 0x4
.byte 0x88
.byte 0x1
.align 4
.LECIE1:
.set .LLCIE1,.LECIE1-.LSCIE1
.4byte .LLFDE1
.LSFDE1:
.4byte .LSFDE1-__FRAME_BEGIN__
.4byte .LFB1
.4byte .LFE1-.LFB1
.byte 0x4
.4byte .LCFI0-.LFB1
.byte 0xe
.byte 0x8
.byte 0x85
.byte 0x2
.byte 0x4
.4byte .LCFI1-.LCFI0
.byte 0xd
.byte 0x5
.byte 0x4
.4byte .LCFI3-.LCFI1
.byte 0x2e
.byte 0x10
.align 4
.LEFDE1:
.set .LLFDE1,.LEFDE1-.LSFDE1
.ident "GCC: (GNU) 2.95.3"
Записан

Страниц: [1] 2 3 ... 6
  Печать  
 
Перейти в: