двойные цифры в C ++ - PullRequest
       29

двойные цифры в C ++

3 голосов
/ 05 октября 2009

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

Ref: http://msdn.microsoft.com/en-us/library/system.double(VS.80).aspx: , .

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

Пример номера: d1 = 97842111437.390091
d2 = 97842111437.390076
d1 и d2 различаются в 16-м и 17-м десятичных разрядах, которые не должны быть значимыми. Ищем способы заставить их обнулить. т.е. d1 = 97842111437.390000 d2 = 97842111437.390000

Ответы [ 5 ]

11 голосов
/ 05 октября 2009

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

1.11111111111118

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

1.1111111111111799942818834097124636173248291015625
1.1111111111111802163264883347437717020511627197265625

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

3 голосов
/ 05 октября 2009

Нет, но мне интересно, относится ли это к каким-либо из ваших проблем (специфических для GCC):

Документация GCC

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

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

3 голосов
/ 05 октября 2009

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

0 голосов
/ 05 октября 2009

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

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

Играть с битами числа напрямую - не лучшая идея.

0 голосов
/ 05 октября 2009

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

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...