2009-10-05 3 views
3

Плавающая точка IEE754 (64 бит) должна правильно представлять 15 значащих цифр, хотя внутреннее представление имеет 17 ditigs. Есть ли способ заставить 16-ю и 17-ю цифры до нуля?цифры двойного типа в C++

Код: http://msdn.microsoft.com/en-us/library/system.double(VS.80).aspx: . .

Помните, что число с плавающей запятой может приближать только десятичное число и что точность числа с плавающей запятой определяет, насколько точно это число приближается к десятичному числу. По умолчанию двойное значение содержит 15 десятичных цифр точности, хотя не более 17 цифр поддерживается внутри. Точность числа с плавающей запятой имеет несколько последствий: . .

Пример NOS: d1 = +97842111437,390091
d2 = +97842111437,390076
d1 и d2 различаются в 16-м и 17-го знаков после запятой, которые не должны быть значительными. Ищете способы заставить их к нулю. т.е. d1 = +97842111437,390000 d2 = 97842111437,390000

+2

Вы говорите о 64-битных поплавках? Как и в 15 значащих десятичных разрядах? – John

+0

Я должен согласиться с Джоном У. Вопрос немного расплывчатый. Внутреннее представление не равно десятичному. –

+0

В двухместных номерах IEEE754 есть 52 бит мантиссы: http://en.wikipedia.org/wiki/Double_precision_floating-point_format Помимо Intel, использующих 80-битные регистры с плавающей запятой с 64 бит мантиссы (около 19 цифр разрешения), I ' никогда не слышал о каком-либо другом «внутреннем представлении». Можете ли вы дать ссылку на то, что вы имеете в виду? – KeyserSoze

ответ

0

Вы должны иметь возможность напрямую изменять биты в свой номер, создав союз с полем для числа с плавающей точкой и интегрального типа того же размера. Затем вы можете получить доступ к битам, которые хотите, и установить их, как хотите. Вот пример, когда я ударяю знаковый бит; вы можете выбрать любое поле, которое вы хотите, конечно.

#include <stdio.h> 

union double_int { 
    double    fp; 
    unsigned long long integer; 
}; 

int main(int argc, const char *argv[]) 
{ 
    double   my_double = 1325.34634; 
    union double_int *my_union = (union double_int *)&my_double; 

    /* print original numbers */ 
    printf("Float %f\n", my_double); 
    printf("Integer %llx\n", my_union->integer); 

    /* whack the sign bit to 1 */ 
    my_union->integer |= 1ULL << 63; 

    /* print modified numbers */ 
    printf("Negative float %f\n", my_double); 
    printf("Negative integer %llx\n", my_union->integer); 

    return 0; 
} 
+0

Я думаю, что я неправильно понял вопрос .... ну, я подожду уточнения, а затем удалю это, если необходимо. –

11

Количество Встречное пример: два ближайших чисел с плавающей точкой к рациональной

1.11111111111118 

(который имеет 15 десятичных цифр)

1.1111111111111799942818834097124636173248291015625 
1.1111111111111802163264883347437717020511627197265625 

Другими словами, не является числом с плавающей запятой, которое начинается с 1.1111111111111800.

3

Этот вопрос немного искажен. Аппаратное обеспечение хранит номера в двоичном, а не в десятичном формате. Так что в общем случае вы не можете сделать точные математику в базе 10. Некоторые десятичные числа (0,1 - один из них!) Не имеют , даже имеют не повторяющееся представление в двоичном формате. Если у вас есть прецизионных требований, таких как это, где вас беспокоит число , имеющее известную точность до ровно 15 десятичных цифр, вам понадобится , чтобы выбрать другое представление для ваших номеров.

3

Нет, но мне интересно, если это имеет отношение к какому-либо из ваших вопросов (GCC конкретные):

GCC Documentation

-ffloat-магазин Не хранить с плавающей точкой переменными в регистрах, и запрещающего другие параметры, которые могут изменить значение с плавающей запятой взято из регистра или памяти.

Эта опция предотвращает нежелательный избыток точность на машинах, таких как 68000, где регистры с плавающей (68881) поддерживать более высокую точность, чем двойной предполагается иметь. Аналогично для архитектуры x86. Для большинства программ избыток предел делает только хорошо, но несколько программ полагаются на точное определение плавающей точки IEEE . Используйте -ffloat-store для таких программ, после их модификации, чтобы сохранить все соответствующие промежуточные вычисления .

+1

Хотя параметр командной строки является специфическим для GCC, проблема не такова. Я использовал компилятор C на компьютерах 68030 и 68040 с «расширенными» числами с плавающей запятой, которые были всего лишь 80-битными представлениями в реализациях 68881. –

0

Вообще говоря, люди заботятся только о чем-то вроде этого («Я хочу только первые х цифры») при отображении номера. Это относительно легко с stringstream s или sprintf.

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

Игра с битами номера напрямую не является отличной идеей.

Смежные вопросы