Прочитал на Википедии про десятичный формат floating point здесь, затем про расширение gcc для этих чисел, решил ради интереса попробовать. Но программа не собирается. Пробовал в Win32 mingw, Linux x64, все равно выдает ошибку, не знает что такое _Decimal32.
int main()
{
_Decimal32 d;
return 0;
}
Что нужно для того чтобы это собралось? И есть ли нативная поддержка этого формата в интеловских процах, или предполагается какая-то эмуляция?
Здравствуйте, NeoCode, Вы писали:
NC>Прочитал на Википедии про десятичный формат floating point здесь, затем про расширение gcc для этих чисел, решил ради интереса попробовать.
Напрасно :)
NC>Но программа не собирается. Пробовал в Win32 mingw, Linux x64, все равно выдает ошибку, не знает что такое _Decimal32.
Что за ошибка, как собираешь, какой стандарт ты задал компилятору, с какими опциями собран сам компилятор? У меня твой пример вполне себе компилируется, а если добавить вычислений, то и работает.
NC>Что нужно для того чтобы это собралось?
Собственно, нужен gcc с включенной поддержкой и включенными расширениями.
NC>И есть ли нативная поддержка этого формата в интеловских процах, или предполагается какая-то эмуляция?
Поддержки нет и не было. За одним разве что мелким исключением — в x87 есть инструкции по записи или чтению в память числа в bcd представлении. Но, разумеется, вычисления с загруженным таким образом числом происходит совсем не по правилам decimal арифметики.
Ну и вообще, в семействе x86 все следы bcd чисел — это в основном артефакты первых процессоров для микрокалькуляторов, которым поддержка такой функциональности была важна (калькулятор же). Так в более современных x86-64 от части соответствующих инструкций уже окончательно избавились, ибо пользы они практически не несут.
L>#pragma pack(push,1) L>union ParsedFloat L>{ L> ParsedFloat( float fvalue = 0.0f ) : value(fvalue) {}
L> bool IsSign() const { return (integer >> 31) != 0; } // Portable sign-extraction
L> float value; L> __int32 integer;
L> // This is the IEEE 754 single-precision format L> struct ieee_t L> { L>#ifdef BIG_ENDIAN L> unsigned int sign : 1; L> unsigned int exponenta : 8; L> unsigned int mantissa : 23; L>#endif L>#ifdef LITTLE_ENDIAN L> unsigned int mantissa : 23; L> unsigned int exponenta : 8; L> unsigned int sign : 1; L>#endif L> }ieee; L>}; L>#pragma pack(pop) L>
L>
Это что? Формат float? Я это и сам могу Вы возможно не поняли о чем я спрашиваю.
Насколько я понял, кроме классических float/double типов по основанию 2 (т.е. mantissa * pow(2, exponenta), могут быть еще float/double по основанию 10, т.е. mantissa * pow(10, exponenta). При той же самой записи например число 0.2 невозможно точно представить в Binary float, но можно точно представить в Decimal float. При этом судя по Википедии это не просто какой-то кастомный класс чисел с плавающей точкой, а стандарт IEEE. Поэтому мне интересна именно поддержка на уровне компиляторов, а также насколько данный формат распространен на аппаратном уровне, поддерживают ли его наиболее распространенные процессорные архитектуры (x86, x64, arm).
Здравствуйте, NeoCode, Вы писали:
NC>Что нужно для того чтобы это собралось? И есть ли нативная поддержка этого формата в интеловских процах, или предполагается какая-то эмуляция?
Здравствуйте, NeoCode, Вы писали:
NC> При той же самой записи например число 0.2 невозможно точно представить в Binary float, но можно точно представить в Decimal float. При этом судя по Википедии это не просто какой-то кастомный класс чисел с плавающей точкой, а стандарт IEEE.
Да.
NC> Поэтому мне интересна именно поддержка на уровне компиляторов, а также насколько данный формат распространен на аппаратном уровне, поддерживают ли его наиболее распространенные процессорные архитектуры (x86, x64, arm).
Эти — нет. Аппаратная поддержка из известных мне есть только в IBM z/Architecture, но это даже не офисное решение. Всё — софтом. В дотнете вроде есть на уровне VM.
Здравствуйте, NeoCode, Вы писали:
NC>Прочитал на Википедии про десятичный формат floating point здесь, затем про расширение gcc для этих чисел, решил ради интереса попробовать. Но программа не собирается. Пробовал в Win32 mingw, Linux x64, все равно выдает ошибку, не знает что такое _Decimal32.
Вот на таком:
$ gcc -v
Using built-in specs.
[...]
Thread model: posix
gcc version 4.7.2 20130108 [gcc-4_7-branch revision 195012] (SUSE Linux)
собралась и работает следующая программа:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
double ba, bb;
ba = strtod(argv[1], NULL);
bb = strtod(argv[2], NULL);
_Decimal32 a = ba;
_Decimal32 b = bb;
_Decimal32 c = a + b;
printf("%g\n", (double) c);
return 0;
}
успешно складывает два числа со ввода.
NC>Что нужно для того чтобы это собралось? И есть ли нативная поддержка этого формата в интеловских процах, или предполагается какая-то эмуляция?
В gcc есть файлик config/dfp.m4, в котором сказано включать это:
Здравствуйте, netch80, Вы писали:
N>собралась и работает следующая программа
Спасибо! Оказывается дело было в том, что я пытался компилировать файл с расширением 'cpp', а надо было 'c'. Т.е. в С++ эти штуки не работают. Но мне чисто поиграться, и на Си сойдет
Кстати, еще там есть числа с фиксированной точкой, тоже любопытная и полезная вещь (особенно для микроконтроллеров всяких где нет нативного float).