Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiplication: uint vs float

Tags:

c++

Why are the two following result different? The result of the following multiplication should be an integer anyway.

uint16_t test = 500.00 * 128.51;
std::cout << test << std::endl; ----> 64254

but

float test = 500.00 * 128.51;
std::cout << test << std::endl; ----> 64255
like image 229
vincedjango Avatar asked Sep 26 '26 02:09

vincedjango


2 Answers

(moving from a comment)

To complete the previously linked duplicate, 500.00 * 128.51 is actually slightly smaller than 64255 (as 128.51 cannot be accurately represented in binary FP).

When casting to an integral type, decimals are discarded (the value is truncated), so your 64254.99999... becomes 64254.

OTOH, when keeping it as a double, you preserve the 64254.9999..., and the default ostream::operator<< behavior is to round at some decimal position when printing, so when displaying it you see it just as 64255.

like image 121
Matteo Italia Avatar answered Sep 27 '26 16:09

Matteo Italia


The result of the following multiplication doesn't have decimals.

Maybe it doesn't in base 10 (decimal), but computers don't work in base 10. They work in base 2, and in base 2 128.51 has more decimals fractional digits than can be stored in the float (or, actually, any similar format — it would require infinite places, much like trying to write out 1/3 in decimal).

This error carries through so, although mathematically 64255 is a whole number, the result of your multiplication is closer to 64254.9999999999927240.

std::cout is automatically rounding this up by default (because it knows that this kind of thing happens); however, during conversion to uint16_t, a dumb truncation happens instead, resulting in the incorrect 64254.

With some I/O manipulator magic, we can see this more clearly:

#include <iostream>
#include <iomanip>

int main()
{
    std::cout << std::fixed << std::setprecision(16) << (500.00 * 128.51) << std::endl;
    std::cout << uint16_t(500.00 * 128.51) << std::endl;
}

// 64254.9999999999927240
// 64254

(live demo)

like image 21
Lightness Races in Orbit Avatar answered Sep 27 '26 15:09

Lightness Races in Orbit