80-битная арифметика с плавающей запятой в C/C++

Предположим, что a, b являются _int64 переменными. Необходимо вычислить sqrt((long double)a)*sqrt((long double)b) в высокоточной 80-битной плавающей запятой.

Пример. (__int64)(sqrt((long double)a)*sqrt((long double)a) + 0.5) != a во многих случаях так и должно быть.

Какой компилятор win32 C/C++ может управлять 80-битной арифметикой с плавающей запятой?


person amuliar    schedule 10.08.2011    source источник
comment
Компилятор Cили C++? Выберите один или прямо скажите, что вам нужны оба.   -  person    schedule 10.08.2011
comment
WTP: Может быть компилятором C или C++ для win32/amd64. Для меня не имеет значения.   -  person amuliar    schedule 10.08.2011
comment
В вашем вопросе используются как _int64 (один подчеркивание), так и __int64 (два подчеркивания). Если это сделано намеренно, в чем разница/смысл?   -  person kevinarpe    schedule 15.08.2016


Ответы (3)


Вероятно, вам не следует использовать плавающую точку для извлечения квадратного корня из целого числа, особенно long double, которое плохо поддерживается и может иметь приблизительное (не точное) sqrtl в некоторых системах. Вместо этого найдите алгоритмы целочисленного квадратного корня.

person R.. GitHub STOP HELPING ICE    schedule 10.08.2011
comment
Это сложнее. Я ищу решения системы диофантных уравнений (лим. до 64-битных целых чисел). Форма ЦЕЛОГО ЧИСЛА sqrtl(a)*sqrtl(b) является наиболее простым представлением возможного решения. - person amuliar; 11.08.2011
comment
Я имею в виду, что есть способы, которыми вы можете извлекать квадратные корни из целых чисел напрямую, без использования плавающей запятой. - person R.. GitHub STOP HELPING ICE; 11.08.2011

Вы уверены, что sqrt() действителен для длинных удвоений?

По крайней мере, в некоторых средах sqrt() предназначен для двойных значений, sqrtf() для чисел с плавающей запятой и sqrtl() для длинных двойных значений.

person kauppi    schedule 10.08.2011
comment
Да. math.h имеет версию: long double sqrt(long double) - person amuliar; 10.08.2011
comment
Функция sqrt(), объявленная в <math.h>, определенно предназначена для двойников, а не для длинных двойников; sqrtl() для длинных двойников. Но есть также общий для типов макрос sqrt(), определенный в <tgmath.h> (если ваш компилятор его поддерживает, это относительно новая функция). - person Keith Thompson; 10.08.2011
comment
@amuliar: это называется sqrtl, а не sqrt. - person Keith Thompson; 10.08.2011
comment
Компилятор Open Watcom C/C++ имеет только версию sqrt. :( - person amuliar; 11.08.2011

Embarcadero C++Builder будет обрабатывать 80-битные числа с плавающей запятой. Используйте тип long double или тип Extnded (импортированный из Delphi). Они одинаковые.

person Rudy Velthuis    schedule 10.08.2011
comment
Да, у него 80 бит, но он терпит неудачу. а = 8642673492431640625L; Результат в Delphi: 8642673492431640624. Компилятор Borland C++ 5.5: 8642673492431640200 - person amuliar; 11.08.2011
comment
Хорошо, я только что попробовал: unsigned __int64 a = 8642673492431640625L; long double ld = a; printf("%0.1Lf\n", ld);, и он печатает: 8642673492431640625.0, что мне кажется правильным. Это было в C++Builder XE. - person Rudy Velthuis; 11.08.2011