Forum > General

StrToFloat - formatted

<< < (2/11) > >>

MathMan:
@J-G - not sure if the following helps your understanding, but I'll try

* you are fiddling with two values 2.55 & 2.5625 which are very different and maybe even got mixed up in your testing such that the results confused you
- 2.5625 = 41 / 16, that means this value can exactly be represented as a float (single,double or extended) because the divisor is a small power of 2 <= as Bart already pointed out
- 2.55 = 51/20, that means this value can not be exactly represented as a float (single, double or extended) because the divisor is a multiple of 5
- the float will contain the closest approximation to '2.55' which, in case of single, is '2.54999952'

* you can calculate at nauseam wrt 2.55 you'll simply never get to 'good = TRUE'
* when calculating wrt 2.5625 you'll get 'good = TRUE' because the floating point value is exact

However, I am currently at a loss to explain where / how you got the info that '2.5625 = 2.562500023841...' - there has to be an intermediate step you overlooked that changed the value to an inexact approximation.

Cheers,
MathMan

J-G:
@Mathman has come back with some interesting infomation but I'll respond to that next.

I've now declared 'Ratio' as Double and can confirm that the 2.55 does return correctly (no trailing rubbish), however, 'Good' still returns false with the (T1*Ratio) = Int(T1*Ratio) test  and True with the A=B test  - - -  that is the logic that defeats me.

I've also tried ReadStr()  which seems more elegant than StrToFloat() and StrToInt() so that is likely to be my 'goto' method in the future. I've only tried it as a replacement for StrToFloat() as yet.

J-G:

--- Quote from: MathMan on June 25, 2022, 02:39:40 pm ---@J-G - not sure if the following helps your understanding, but I'll try
--- End quote ---
And you have succeded!  - I was aware of the issues concerned with accurate representation of 'floats' but your explanation is succinct.

--- Quote from: MathMan ---* you are fiddling with two values 2.55 & 2.5625 which are very different and maybe even got mixed up in your testing such that the results confused you
--- End quote ---
I wasn't 'confused',   I confused you by referencing two different subjects and providing a very poor (inaccurate) example   :-[    -  I was just trying to indicate that the were values beyond the d.places needed.

The two figures derive from a TPI input of 20.4 and 20.5  which I'd found to give differing results. I'd also had a problem with 24.8 TPI which had returned 3.099999905 rather than 3.1.

--- Quote from: MathMan --- - 2.5625 = 41 / 16, that means this value can exactly be represented as a float (single,double or extended) because the divisor is a small power of 2 <= as Bart already pointed out
--- End quote ---
Since the minimum allowable figure is 20, I hadn't seen 41/16  -  the first 'good' pairing was at 82/32.

--- Quote from: MathMan --- - 2.55 = 51/20, that means this value can not be exactly represented as a float (single, double or extended) because the divisor is a multiple of 5
- the float will contain the closest approximation to '2.55' which, in case of single, is '2.54999952'

* you can calculate ad nauseam wrt 2.55 you'll simply never get to 'good = TRUE'
* when calculating wrt 2.5625 you'll get 'good = TRUE' because the floating point value is exact
--- End quote ---
I completely understand that logic  and even see why using 'Double' is better  - but still cannot see how  A=B  does return true ???  (They are declared : single)  -  I'm grateful that it does!

--- Quote from: MathMan ---However, I am currently at a loss to explain where / how you got the info that '2.5625 = 2.562500023841...' - there has to be an intermediate step you overlooked that changed the value to an inexact approximation.

Cheers,
MathMan

--- End quote ---
Again - appologies for that particular confusion  :-[

dseligo:

--- Quote from: J-G on June 25, 2022, 02:58:27 pm ---I've now declared 'Ratio' as Double and can confirm that the 2.55 does return correctly (no trailing rubbish), however, 'Good' still returns false with the (T1*Ratio) = Int(T1*Ratio) test  and True with the A=B test  - - -  that is the logic that defeats me.

--- End quote ---

Single and double types (IEEE 754) can't always represent exact decimal number and that is the reason your test fails.

What you can do is compare difference between two number and if it is within certain precision you can say there are same, maybe something like:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Good := abs(T1*Ratio - Int(T1*Ratio)) < 0.00001;
Maybe you could use 'Currency' type. You won't have problems like this with Currency, but it is limited to 4 decimal places.

J-G:

--- Quote from: dseligo on June 25, 2022, 03:49:12 pm ---
--- Quote from: J-G on June 25, 2022, 02:58:27 pm ---I've now declared 'Ratio' as Double and can confirm that the 2.55 does return correctly (no trailing rubbish), however, 'Good' still returns false with the (T1*Ratio) = Int(T1*Ratio) test  and True with the A=B test  - - -  that is the logic that defeats me.

--- End quote ---
Single and double types (IEEE 754) can't always represent exact decimal number and that is the reason your test fails.
--- End quote ---
Whilst I understand the problem of exact representaion of decimal numbers, that doesn't tell me why assigning  A (a Single) to (T1*Ratio)  and B (another Single) to Int(A) -- effectively Int(T1*Ratio)  --- returns in a different Boolean result than a direct comparison of the two.

--- Quote from: dseligo ---What you can do is compare difference between two number and if it is within certain precision you can say there are same, maybe something like:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---Good := abs(T1*Ratio - Int(T1*Ratio)) < 0.00001;
--- End quote ---
That may well be a viable option as well  -  I have tried the 'SameValue((T1*Ratio),Int(T1*Ratio),Tol) -- where I've set 'Tol' to various values such as 0.001 and 0.000001  -- but without success.

--- Quote from: dseligo ---Maybe you could use 'Currency' type. You won't have problems like this with Currency, but it is limited to 4 decimal places.
--- End quote ---
Regrettably there is a likelyhood that a viable Ratio can have as many as 8 d.Places - certainly 6 - but thanks for the suggestion.#