why is 1.85 is round up to 1.9 and 1.95 is round down to 1.9 ?

 

why is when i round 1.85 to 1 decimal place it become 1.9 

and 1.9 5 round down so

it become become 1.9

and 1.65 round down so it  become 1.6 

the out pout , was like this :

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.15: 1.1

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.25: 1.2

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.35: 1.4

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.45: 1.4

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.55: 1.6

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.65: 1.6

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.75: 1.8

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.85: 1.9

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.95: 1.9

2023.09.27 19:50:46.410 test (EURUSD,H1) number 1.95: 2.0

and the code was like this , can you you help me to understand the " %.f " placeholder or ( format specifier )    please !! 
void OnStart()
  {
double number1 = 1.15 ; 
PrintFormat( "number 1.15: %.1f", number1 ); 
double number2 = 1.25 ; 
PrintFormat( "number 1.25: %.1f", number2 ); 
double number3 = 1.35 ; 
PrintFormat( "number 1.35: %.1f", number3 ); 
double number4 = 1.45 ; 
PrintFormat( "number 1.45: %.1f", number4 ); 
double number5 = 1.55 ; 
PrintFormat( "number 1.55: %.1f", number5 ); 
double number6 = 1.65 ; 
PrintFormat( "number 1.65: %.1f", number6 ); 
double number7 = 1.75 ; 
PrintFormat( "number 1.75: %.1f", number7 ); 
double number8 = 1.85 ; 
PrintFormat( "number 1.85: %.1f", number8 ); 
double number9 = 1.95 ; 
PrintFormat( "number 1.95: %.1f", number9 ); 
double number10 = 2.0 ; 
PrintFormat( "number 1.95: %.1f", number10 ); 

  }
 

Because the exact values 1.85 and 1.95 cannot be represented in double floating point precision, because it is binary and not decimal.

It will become:

  • 1.8500000000000000888178419700125232338905334472656250
  • 1.9499999999999999555910790149937383830547332763671875

So, from the above two values, can you see why one will round up and the other will round down to 1.9?

Indecently 1.9 is actually expressed as 1.899999999999999911182158029987476766109466552734375

For reference: https://www.exploringbinary.com/floating-point-converter/

Decimal to Floating-Point Converter
Decimal to Floating-Point Converter
  • Rick Regan
  • www.exploringbinary.com
This is a decimal to binary floating-point converter. It will convert a decimal number to its nearest single-precision and double-precision IEEE 754 binary floating-point number, using round-half-to-even rounding (the default IEEE rounding mode). It is implemented with arbitrary-precision arithmetic, so its conversions are correctly rounded. It...
 

Also, before you post, please run a few searches. This has been discussed many times.

Forum on trading, automated trading systems and testing trading strategies

MathRound fails for one particular number

Fernando Carreiro, 2018.01.01 22:08

He means that the value "0.69" cannot be exactly represented given the way a floating point number works (based on binary and not decimal representation) - hence, why the value gets represented as "0.68999999..." (see below).

You can never really "normalize" it and it is the main reason why both @whroeder1 and myself contest the use of the NormalizeDouble() function. It should in the very least be renamed to something like "RoundDigits()" because it is more of a "rounding" function and does not "normalize" in any way or fashion.


https://www.h-schmidt.net/FloatConverter/IEEE754.html

EDIT: Please note that the above images are for examples of representation in the 4-byte "float", and not the 8-byte "double" which offers more precision but still cannot represent the value "0.69" exactly due to the "binary" nature of the format.

EDIT2: For future readers that have difficulty understanding (or accepting) this concept, of decimal values not having an exact representation with a "float" or a "double", here is an article worth reading:

Why 0.1 Does Not Exist In Floating-Point

Many new programmers become aware of binary floating-point after seeing their programs give odd results: “Why does my program print 0.10000000000000001 when I enter 0.1?”; “Why does 0.3 + 0.6 = 0.89999999999999991?”; “Why does 6 * 0.1 not equal 0.6?” Questions like these are asked every day, on online forums like stackoverflow.com.

The answer is that most decimals have infinite representations in binary. Take 0.1 for example. It’s one of the simplest decimals you can think of, and yet it looks so complicated in binary:


Decimal 0.1 In Binary ( To 1369 Places

The bits go on forever; no matter how many of those bits you store in a computer, you will never end up with the binary equivalent of decimal 0.1.

... Read the rest of the article at: http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

 
thank you ^^
 

For your particular case, using NormalizeDouble() is just enough for those edge (half-way) numbers:

void OnStart()
  {
   double number1 = 1.15 ;
   double number2 = 1.25 ;
   double number3 = 1.35 ;
   double number4 = 1.45 ;
   double number5 = 1.55 ;
   double number6 = 1.65 ;
   double number7 = 1.75 ;
   double number8 = 1.85 ;
   double number9 = 1.95 ;
   Print("number 1.15: ", NormalizeDouble(number1, 1));
   Print("number 1.25: ", NormalizeDouble(number2, 1));
   Print("number 1.35: ", NormalizeDouble(number3, 1));
   Print("number 1.45: ", NormalizeDouble(number4, 1));
   Print("number 1.55: ", NormalizeDouble(number5, 1));
   Print("number 1.65: ", NormalizeDouble(number6, 1));
   Print("number 1.75: ", NormalizeDouble(number7, 1));
   Print("number 1.85: ", NormalizeDouble(number8, 1));
   Print("number 1.95: ", NormalizeDouble(number9, 1));
  }

Expected output:

 number 1.15: 1.2
 number 1.25: 1.3
 number 1.35: 1.4
 number 1.45: 1.5
 number 1.55: 1.6
 number 1.65: 1.7
 number 1.75: 1.8
 number 1.85: 1.9
 number 1.95: 2.0

Note that using DoubleToString() function as DoubleToString(number, 1) gives wrong values, the same as PrintFormat() and StringFormat().

EDIT:

@Fernando Carreiro  is referring to what is called representation errors in floating-point numbers.

NormalizeDouble() handles those errors in most (BUT NOT ALL) of the cases.

BTW: NormalizeDouble() itself has another kind of rounding issues, but this is not the main subject of this post.