0

I have this program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char buf[32];

  snprintf(buf, 32, "%.2f", 447.065);
  printf("447.065 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.165);
  printf("441.165 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.265);
  printf("447.265 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.365);
  printf("441.365 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.465);
  printf("447.465 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.565);
  printf("441.565 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.665);
  printf("447.665 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.765);
  printf("441.765 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.865);
  printf("441.865 --> %s\n", buf);

  snprintf(buf, 32, "%.2f", 447.965);
  printf("441.965 --> %s\n", buf);

}

This is the output:

447.065 --> 447.06 
441.165 --> 447.17 
447.265 --> 447.26 
441.365 --> 447.37 
447.465 --> 447.46 
441.565 --> 447.56 
447.665 --> 447.67 
441.765 --> 447.76 
441.865 --> 447.87 
441.965 --> 447.96 

From the output I can't understand what are the rules used for rounding the values.

I've read around and found references that the "Banker's rounding" algorithm is used in snprintf, but to me the values I got don't seem to match the values that I would have with the Banker's algorithm.

Any thoughts on this issue ?

zentrunix
  • 2,098
  • 12
  • 20
  • theres no rounding in your `printf`, it prints strings, its all happening in `snprintf`, which afaik is not standard C++ – 463035818_is_not_an_ai Jan 24 '23 at 13:23
  • There is no such number that's `447.065` exactly. It's a mirage, and an illusion. It does not exist. The closest number that can be represented is slightly less than that, because floating point math is broken. – Sam Varshavchik Jan 24 '23 at 13:23
  • 1
    @463035818_is_not_a_number `std::snprintf` was added in C++11. :) I still wouldn't use it though (or any `printf` or `scanf` or similar C function). – Some programmer dude Jan 24 '23 at 13:26
  • https://stackoverflow.com/users/4117728/463035818-is-not-a-number yes, of course it's in snprintf – zentrunix Jan 24 '23 at 13:31
  • 3
    `xx.xx5` will be rounded up normally but if the number you start with isn't exactly `xx.xx5` due to the precision of floating point numbers (e.g. the true number might be `xx.xx499999999`) then it might be rounded down instead – Alan Birtles Jan 24 '23 at 13:32
  • 3
    As for your problem and helping you understand it, print with larger precision. Try `%.10f` instead in `snprintf`. The values will very likely surprise you. – Some programmer dude Jan 24 '23 at 13:37
  • 3
    @zentrunix "Banker's rounding" -- It's ironic that you mention "banker's rounding", since many banks and financial institutions forbid usage of floating point variables and functions within their programs, for the exact reason you are seeing here. If you want to deal with monetary or other values, and want the arithmetic to be exact, either use integers, or use a fixed point type (usually from third party code or your own types). Unfortunately, there is no standard type in C++ that supports these types of calculations. – PaulMcKenzie Jan 24 '23 at 13:43

0 Answers0