Numbers Greater Than DBL_MAX Should Convert To DBL_MAX When Rounding Toward Zero

I was testing David Gay’s most recent fixes to strtod() with different rounding modes and discovered that Apple Clang C++ (Xcode) and Microsoft Visual Studio C++ produce incorrect results for round towards zero and round down modes: their strtod()s convert numbers greater than DBL_MAX to infinity, not DBL_MAX. At first I thought Gay’s strtod() was wrong, but Dave pointed out that the IEEE 754 spec requires such conversions to be monotonic.

Continue reading “Numbers Greater Than DBL_MAX Should Convert To DBL_MAX When Rounding Toward Zero”

NaNs, Infinities, and Negative Numbers In Loan Calculators

I’ve encountered several NaNs over the years in the normal course of using various websites and apps. I’ve only documented two of them: one in a media player, and one in a podcast app. I recently ran into another one using a loan calculator website. Rather than reporting on just that one, I decided to look for more and report on anything I found all at once.

I found many more errors — NaNs, but also infinites, negative numbers, and one called “incomplete data”, whatever that means — all on websites within the top Google search results for “loan calculator”. All I had to do to elicit these errors was to enter large numbers. (And in one case, simply including a dollar sign.) All of the errors arise from the use of floating-point arithmetic combined with unconstrained input values. Some sites even let me enter numbers in scientific notation, like 1e308, or even displayed them as results.

Floating point error in loan calculator

Continue reading “NaNs, Infinities, and Negative Numbers In Loan Calculators”

Incorrect Hexadecimal to Floating-Point Conversions in David Gay’s strtod()

I wrote about Visual C++ incorrectly converting hexadecimal constants at the normal/subnormal double-precision floating-point boundary. It turns out that David Gay’s strtod() also has a problem with the same inputs, converting them all to 0 instead of 0x1p-1022.

I have emailed Dave Gay to report the problem; I will update this post when he responds.

Update 2/28/24

The bug is now fixed (after several iterations) and is available in netlib. Thanks to Dave Gay for the quick turnaround.

Typically, I use Gay’s strtod() to check the outputs of other conversion routines (examples: Visual C++, GCC and GLIBC, PHP). In this case, the roles were reversed: I used another C implementation, Apple Clang C++ , to check Gay’s strtod().

Incorrect Hexadecimal to Floating-Point Conversions in Visual C++

Martin Brown, through a referral on his Stack Overflow question, contacted me about incorrect hexadecimal to floating-point conversions he found in Visual C++, specifically conversions using strtod() at the normal/subnormal double-precision floating-point boundary. I confirmed his examples, and also found an existing problem report for the issue. It is not your typical “off by one ULP due to rounding” conversion error; it is a conversion returning 0 for a non-zero input or returning numbers with exponents off by binary orders of magnitude.

Continue reading “Incorrect Hexadecimal to Floating-Point Conversions in Visual C++”

Anomalies In IntelliJ Kotlin Floating-Point Literal Inspection

IntelliJ IDEA has a code inspection for Kotlin that will warn you if a decimal floating-point literal exceeds the precision of its type (Float or Double). It will suggest an equivalent literal (one that maps to the same binary floating-point number) that has fewer digits, or has the same number of digits but is closer to the floating-point number.

Screenshot in IntelliJ IDEA of hovering over a flagged 17-digit literal with a suggested 10-digit replacement
Hovering over a flagged 17-digit literal suggests a 10-digit replacement.

For Doubles for example, every literal over 17-digits should be flagged, since it never takes more than 17 digits to specify any double-precision binary floating-point value. Literals with 16 or 17 digits should be flagged if there is a replacement that is shorter or closer. And no literal with 15 digits or fewer should ever be flagged, since doubles have of 15-digits of precision.

But IntelliJ doesn’t always adhere to that, like when it suggests an 18-digit replacement for a 13-digit literal!

Screenshot of IntelliJ IDEA suggesting an 18-digit replacement for a 13-digit literal
An 18-digit replacement suggested for a 13-digit literal!

Continue reading “Anomalies In IntelliJ Kotlin Floating-Point Literal Inspection”

Another NaN In the Wild

I see these from time to time, but I don’t always capture them; here’s one I saw recently while playing a podcast:

A NaN in an ad in the app Castbox (partial image)
A NaN in an ad in the app Castbox (click for full image).

(According to Castbox, this is an error in the ad and is out of their control.)

Visual C++ strtod(): Still Broken

About a year ago Bruce Dawson informed me that Microsoft is fixing their decimal to floating-point conversion routine in the next release of Visual Studio; I finally made the time to test the new code. I installed Visual Studio Community 2015 Release Candidate and ran my old C++ testcases. The good news: all of the individual conversion errors that I wrote about are fixed. The bad news: many errors remain.

Continue reading “Visual C++ strtod(): Still Broken”

PHP Converts 2.2250738585072012e-308 Incorrectly

While testing my new decimal to floating-point converter I discovered a bug in old territory: PHP incorrectly converts the number 2.2250738585072012e-308.

<?php printf("%.17g",2.2250738585072012e-308); ?>

This prints 2.2250738585072009E-308; it should print 2.2250738585072014e-308. (I verified that the internal double value is wrong; the printed value correctly represents it.)

Continue reading “PHP Converts 2.2250738585072012e-308 Incorrectly”

Gay’s strtod() Returns Zero For Inputs Just Above 2^-1075

While running some of GCC’s string to double conversion testcases I discovered a bug in David Gay’s strtod(): it converts some very small subnormal numbers incorrectly. Unlike numbers 2-1075 or smaller, which should convert to zero under round-to-nearest/ties-to-even rounding, numbers between 2-1075 and 2-1074 should convert to 2-1074, the smallest number representable in double-precision binary floating-point. strtod() correctly converts the former to 0, but it incorrectly converts the latter to 0 as well.

(Update 11/25/13: This bug has been fixed.)

Continue reading “Gay’s strtod() Returns Zero For Inputs Just Above 2^-1075”

GLIBC strtod() Incorrectly Converts 2^-1075

A reader of my blog, Water Qian, reported a bug to me after reading my article “How GLIBC’s strtod() Works”. I recently tested strtod(), which was was fixed to do correct rounding in glibc 2.17; I had found no incorrect conversions.

Water tested the conversion of 2-1075 — in retrospect an obvious corner case I should have tried — and found that it converted incorrectly to 0x0.0000000000001p-1022. That’s 2-1074, the smallest double-precision value. It should have converted to 0, under round-to-nearest/ties-to-even rounding.

(Update 11/13/13: This bug has been fixed for version 2.19.)

Continue reading “GLIBC strtod() Incorrectly Converts 2^-1075”

Copyright © 2008-2024 Exploring Binary

Privacy policy

Powered by WordPress