math problem

BlitzPlus Forums/BlitzPlus Programming/math problem

Chrisbris(Posted 2016) [#1]
Hi....

how would one go about checking a sum of division returns a whole number ?


Kryzon(Posted 2016) [#2]
Whatever the expression is (sums, divisions, subtractions etc.), you want to check if it's round (an integer)?
If any of the values in the expression is a floating point, then all the other values in the expression will also be cast to floating point.
This means the result of the expression will be a floating point value.

I'm sure there's a foolproof way to do what you want by checking the bits of that floating point result number, seeing if the exponent value is as large as the number of digits in the significand (see here http://floating-point-gui.de/formats/fp/).

But I think the simple Blitz way would be:
myExpression# = ( x + y ) / z ... ;Whatever the expression is.

;The following removes the decimal part of the result of the expression.
;3.141 becomes 3, for example.
truncatedExpression% = Int( myExpression )

If ( myExpression = truncatedExpression ) Then

	;The original value of the expression is the same as its truncated value.
	;This means: the expression is a whole number, an integer.

EndIf



Kryzon(Posted 2016) [#3]
Whatever the expression is (sums, divisions, subtractions etc.), you want to check if it's round (an integer)?
If any of the values in the expression is a floating point, then all the other values in the expression will also be cast to floating point.
This means the result of the expression will be a floating point value.

I'm sure there's a foolproof way to do what you want by checking the bits of that floating point result number, seeing if the exponent value is as large as the number of digits in the significand (see here http://floating-point-gui.de/formats/fp/).

But I think the simple Blitz way would be:
myExpression# = ( x + y ) / z ... ;Whatever the expression is.

;The following removes the decimal part of the result of the expression.
;3.141 becomes 3, for example.
truncatedExpression% = Int( myExpression )

If ( myExpression = truncatedExpression ) Then

	;The original value of the expression is the same as its truncated value.
	;This means: the expression is a whole number, an integer.

EndIf



Floyd(Posted 2016) [#4]
If you are talking about integer arithmetic then the expression ( a mob b ) will be zero only when b exactly divides a.

This will also for work for floating point numbers if they are small enough, no more than 2^24 in absolute value.

For floats outside that range, I'm not sure. It may still work. But be aware that numbers may not be what you think they. Example, is 3^16 divisible by 2? Of course not, but the mod 2 test will tell you it is.

Set x# = 3^16 and check the value of ( x Mod 2 ). It is zero, so x is claimed to be even, divisible by 2. The explanation is that x is not exactly 3^16.

3^16 is exactly 43046721. But due to the limited precision of floats x actually has the value 43046720 and is divisible by 2.

And now for my usual warning about Blitz/3D/Plus Print when used with floats. The output is rounded to six digits.
So if you Print x you will get 43046700. But if you Print Int(x) you will see the correct value, 43046720.


Chrisbris(Posted 2016) [#5]
hmmmm

that all sounds rather complicated ....

If a sum of division = a floating point number.... and im talking small numbers..... highest being less than 30.

I wondered if in blitz there was a way to determine the answer is or is not an integer.

am I right in saying the code example just rounds the number to an integer ?
as I don't want to do that , just need to know the result as in was the answer an integer or not.

thx


Midimaster(Posted 2016) [#6]
It is so easy... But It depends on the variable type you are using. Are your variables INTEGERs oder FLOATS?

Here is a way, if they are INTEGER:
A%=40
B%=5
C%=6
Print IsInteger(A,B)
Print IsInteger(A,C)

Function IsInteger(x%,y%)
     If x MOD y=0
          Return TRUE
     Endif
     Return FALSE
End Function



Floyd(Posted 2016) [#7]
If you just want to check the value of a single floating point number, call it sum#, then compare it with Int(Sum#).

Int() rounds to nearest integer. If Int(Sum#) = Sum then Sum was already an integer.

As long as you are not dealing with huge values, too big to fit in an integer, then this will work.


RemiD(Posted 2016) [#8]
@Kryzon>>Thanks for the idea, good stuff !


Kryzon(Posted 2016) [#9]
Floyd is right, Int() rounds the number which is not the same as truncating it, like I wrote before, but it still works the same for comparing the expression against its rounded version.

This is how Blitz3D does it:
https://github.com/blitz-research/blitz3d/blob/647f304ef81387d8235b084bb1d9cb7ba5ff139e/compiler/exprnode.cpp#L237

The _RC_NEAR flag is what controls this behaviour, telling it to round the float to the nearest integer, as according to this:
http://www.codercorner.com/FPUFun.htm


Chrisbris(Posted 2016) [#10]
thank you all for your help
much appreceiated