problem with NormalizeDouble - page 2

 
@Ryan L Johnson #:

Thanks, Fernando. I actually really want to use floor to make my code more efficient.

I think that I'm struggling to technically communicate a bit here. When I said, "hard coded value substitution of _Point," what I meant is that I need custom _Point-like data that can be auto-detected from any double, and not only from symbol related doubles. Similarly, my code retrieves custom digits in lieu of _Digits. This is the part where I don't see a way to avoid using MQL5 string functions. In other words, my code is ready to be put into a custom function that could be a truncating version of NormalizeDouble(double,digits) such as TruncateDouble(double,digits).

Floating point numbers don't necessarily have a fixed number of digits (its binary, not decimal). So using strings is not only inefficient but their representation can also be "technically" incorrect.

For example, the number 0.69 has two decimal places (using decimal representation), but when stored in a binary "float" data-type it becomes 0.689999997615814208984375. So how many digits does it really have?

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/

 
Fernando Carreiro #:
You can never really "normalize" it

Whoa.😳 Now that is a technical communication.

I see that "[I] can never really 'normalize' it..." I'm done trying to do the impossible. Thanks again.