C ++ Точное поведение с двойной / длинной двойной

0

Мне просто интересно что-то.

У меня есть следующий код:

if (d1 == 2.3)
    cout << "2.3 is my value\n";
if (d1 == 2.2999999999999998)
    cout << "2.2999999999999998 is my value\n";

VS2013 С++ 11 скриншотов

Изображение 174551

Изображение 174551

И это происходит в обоих случаях. Я знаю, что точность для double - это 15decimals, поэтому мне придется использовать более подходящий тип для данных такого типа.

Может ли кто-нибудь связать мне подробную ссылку? А также "способ" хранить только "2,3" или данные с большей точностью, чем 2.2999999999999998? (длинный двойной бросок меня complie ошибка

Error   1   error C2398: Element '1': conversion from 'long double' to 'const 
std::complex<double>::_Ty &' requires a narrowing conversion...

Благодарю.

Изменение: добавлен комплекс

Изображение 174551

  • 1
    Попробуйте прочитать этот вопрос . Кроме того, вы пробовали complex<long double> ?
  • 0
    Да, я пробовал со сложным <long double> и нет ошибки компиляции, но они оба хранилища все еще 2.99999999999998
Показать ещё 3 комментария
Теги:
type-conversion
precision

2 ответа

4
Лучший ответ

Это характер плавающей запятой - нет способа представить 2.3 точно как двоичный файл с плавающей запятой.

"2.3" в вашем первом тесте не может быть представлен точно в двоичном формате, поэтому он хранится как ближайший возможный double, который равен 2.2999999999999998.
Другими словами, оба if выполняют одинаковое сравнение.

  • 0
    Я знаю о бинарной проблеме, так что я просто думал о том, как насчет какого-то «строкового» преобразования памяти или типа с большей точностью, но long double выдает мне ошибку, которую я написал.
  • 2
    @blacai Вам нужно бесконечное количество памяти, чтобы точно представлять все числа. Вы всегда будете где-нибудь сталкиваться с пределом. Вы можете решить, какая точность вам нужна, а затем реализовать ее самостоятельно, но, вероятно, это того не стоит.
1

возможно, это может помочь вам: http://www.cplusplus.com/forum/beginner/34088/

Насколько я могу судить, похоже, нет реальной ссылки, кроме как с используемым вами компилятором. Попробуйте http://msdn.microsoft.com. Я полагаю, что 2.2999999999999998 округляется до ближайшего двойного значения, которое будет 2,3, или наоборот, как предлагает другой ответчик. если вы хотите длинные двойные литералы, вам нужно добавить L в конце вашего литерала:

//checks for equalty to a double
if (d1 == 2.2999999999999998)
    cout << d1 << " == 2.2999999999999998 ?\n";
//checks for equalty to a long double
if (d1 == 2.2999999999999998L)
    cout << d1 << " == 2.2999999999999998L ?\n";

btw: почему вы не используете

complex<long double>

?

  • 0
    Cplusplus форумы и учебные пособия, пожалуйста, не. Cplusplus является источником ошибок, устаревших практик и недоразумений
  • 0
    Как я уже говорил ранее, я также пытаюсь использовать сложный <long double>, но мне кажется, что то же самое происходит с 2.999999999999998.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню