NormalizeDouble paradox

 

Good afternoon!

As much as I read this Help section, I still can't figure out WHERE that fractional 1 at the end comes from.

Keep in mind that when a normalised number is printed to the Journal using Print(), it may contain more decimal places than you expect. For example,

double a=76.671;// normalized number with 3 decimal places
Print("Print(76.671)=",a);// print it as it is
Print("DoubleToString(a,8)=",DoubleToString(a,8));// print it with the specified accuracy

is output in the terminal:

DoubleToString(a,8)=76.67100000
Print(76.671)=76.67100000000001

 
transcendreamer:

good afternoon!

As much as I read this Help section, I still can't figure out WHERE that fractional 1 at the end comes from.

Keep in mind that when a normalised number is output to the Journal using Print(), it may contain more decimal places than you expect. For example,

double a=76.671;// normalized number with 3 decimal places
Print("Print(76.671)=",a);// print it as it is
Print("DoubleToString(a,8)=",DoubleToString(a,8));// print it with the specified accuracy

is output in the terminal:

DoubleToString(a,8)=76.67100000
Print(76.671)=76.67100000000001

The double type has accuracy limitations due to which errors may occur.

I recommend this article: https://www.mql5.com/ru/articles/1561

Особенности работы с числами типа double в MQL4
Особенности работы с числами типа double в MQL4
  • 2009.11.02
  • MetaQuotes Software Corp.
  • www.mql5.com
В данной заметке собраны советы по решению наиболее часто возникающих ошибок при работе с числами типа double в программах на MQL4.
 
ENSED:

The double type has limitations in accuracy, which can lead to errors.

I recommend this article: https://www.mql5.com/ru/articles/1561

I see the recommendation, thank you.

You can use DoubleToStr when outputting

but it's not clear where that one is coming from in the first place!

If I was doing division/multiplication, OK, it's OK, it's an error.

But in a constant? Which I prescribed myself?

It turns out I have to use rounding for a constant that initially does not have this precision

and most importantly, trust in what is actually stored in the double variable is undermined!

 

Quote from the documentation

Необходимо помнить, что вещественные числа хранятся в памяти компьютера с некоторой ограниченной точностью в двоичной системе счисления, в то время как общепринятой в использовании является десятичная система счисления. Поэтому многие числа, которые точно записываются в десятичной системе, в двоичной системе можно записать только в виде бесконечной дроби.

For example, the numbers 0.3 and 0.7 are represented in the computer as infinite fractions, while the number 0.25 is stored exactly as it is a power of two.

 
stringo:

Quote from the documentation

interesting...

I'm already guessing that it's not in MQL but somewhere deeper, at the level of 80s standards

but still very strange...

I haven't seen it in any other application language

it would be reasonable to have some workarounds at the level of MQL language itself

 

and it still doesn't explain why the code below gives out 0000000001 tails

current=NormalizeDouble(GlobalVariableGet("Equity-"+portfolio_id),2);

text = "Positions closed at " + (string)current + " for portfolio: " + portfolio_name;

if(!automatic) MessageBox(text,""); else Print(text);

because I did the normalization

and the number is still tailed.

 
transcendreamer:

interesting...

I'm already guessing that it's not about MQLs but somewhere deeper down at the level of 80's standards

but it's still very strange...

I haven't seen this in any other application language

it would be reasonable to have some workarounds at the level of MQL

What's so hard about it?

If you need accuracy down to 4 digits. Multiply the number by 10000, discard the fractional part and divide by 10000.

The math functions of mql can be found in the documentation.

 

text = "Positions closed at " + (string)current + " for portfolio: " + portfolio_name;

DoubleTo String for current and you will be fine

 

Yes, I've already realised we need to force rounding

NormalizeDouble apparently fails to do the job

 
transcendreamer:

Yes, I've already realised we need to force rounding

NormalizeDouble does not seem to do the job

NormalizeDouble is exactly how it works (and has always worked this way, starting from the first MQL)

A number is multiplied by 10 to the power of digits, converted to integer form (discarding the fractional part), and then divided by 10 to the power of digits

What is the problem? Breaking the pattern?

 
stringo:

NormalizeDouble works exactly like this (and has always worked like this since the first MQL)

The number is multiplied by 10 to the power of digits, converted to integer form (discarding the fractional part), and then divided by 10 to the power of digits

What is the problem? Breaking the pattern?

A pattern break is that even after normalization there are tails!