Giving the right number of points in a wave according to a variable failed

I have kind of a problem to give a proper number of point to a wave

Function Test1(beg,fin,TimeWin,TimeStep)
variable beg,fin,TimeWin,TimeStep
variable cntmax
cntmax=(fin-beg-TimeWin)/TimeStep+1
print/D "cntmax =",cntmax
Make/N=(cntmax)/D zzz
duplicate/O zzz, Test
killwaves zzz
End
Now try this:

Test1(0,120,2,0.2)

edit Test

Then try this one (replace the value TimeWin by 0.4):

Test1(0,120,0.4,0.2)

edit Test
The function prints cntmax = 599 but the wave 'Test' has only 598 points !!!!

Why?
If anyone has a clue thanks a lot,
Youpi
This sort of thing can happen whenever Igor is expecting an integer. In spite of the Print/D results, cntmax is not an integer as you can see if you add
Print cntmax == round(cntmax)

You will find it prints zero.

So you will need to use
variable cntmax= round((fin-beg-TimeWin)/TimeStep+1)


This happens because some low level code (before the value gets to the Make code) converts the double to an integer using a simple intval= doubleval assignment and the compiler uses truncation. Because this is happening at a low level, changing it to use rounding could introduce unwanted side effects.
Larry Hutchinson wrote:
This sort of thing can happen whenever Igor is expecting an integer. In spite of the Print/D results, cntmax is not an integer as you can see if you add
Print cntmax == round(cntmax)

You will find it prints zero.

So you will need to use
variable cntmax= round((fin-beg-TimeWin)/TimeStep+1)


This happens because some low level code (before the value gets to the Make code) converts the double to an integer using a simple intval= doubleval assignment and the compiler uses truncation. Because this is happening at a low level, changing it to use rounding could introduce unwanted side effects.


Thanks

I don't understand because the value is an integer = 598 there should not be coma or extra zeros to be expected.
If I use Test1(0,120,2,0.2), the value is also an integer and it is equal to 591 and does not generate any problem.
Is there any explanation?


youpi wrote:

I don't understand because the value is an integer = 598 there should not be coma or extra zeros to be expected.
If I use Test1(0,120,2,0.2), the value is also an integer and it is equal to 591 and does not generate any problem.
Is there any explanation?

Because the value of the cntmax variable isn't actually 598, it's 598.9999999999998863131622783839702606201 due to floating point round off error. You can see this if you use this test function:
Function Test1(beg,fin,TimeWin,TimeStep)
    variable beg,fin,TimeWin,TimeStep
    variable/D cntmax
    cntmax=(fin-beg-TimeWin)/TimeStep+1
    print "cntmax =",cntmax
    printf "%.40g\r", cntmax
    Make/N=(cntmax) zzz
    print "points in wave:", numpnts(zzz)
    killwaves zzz
End


note that if, in the function, you add cntmax=599, instead of the current assignment, this works as you expect it to.
youpi][quote=Larry Hutchinson wrote:
This sort of thing can happen whenever Igor is expecting an integer. In spite of the Print/D results, cntmax is not an integer as you can see if you add
Print cntmax == round(cntmax)

You will find it prints zero.

So you will need to use
variable cntmax= round((fin-beg-TimeWin)/TimeStep+1)


This happens because some low level code (before the value gets to the Make code) converts the double to an integer using a simple intval= doubleval assignment and the compiler uses truncation. Because this is happening at a low level, changing it to use rounding could introduce unwanted side effects.




I don't exactely understand what you mean by "igor is expecting an integer" but if I use

Function Test2 (beg,fin,TimeWin,TimeStep)
variable beg,fin,TimeWin,TimeStep
variable cntmax
cntmax=(fin-beg-TimeWin)/TimeStep+1 // ((120-0-0.4)/0.2)+1=599
variable temppo=599
if(cntmax==temppo)
print "Oki"
Endif
print cntmax
Make/N=(cntmax)/D zzz
duplicate/O zzz, Test
killwaves zzz
End

Here I just want Igor to recognize my variable as being equal to 599 and it does not for Test2(0,120,0.4,0.2)
We can not just round the value to make it right, what if my variable "temppo" is not a integer?
I would like to make sure that Igor can properly compare 2 variables.
Can you tell me if there are conditions where it can not, because so far I have used if loops for several of my analysis and I would like to make sure that I don't have to redo it all.
Thanks for your help
Youpi
The key is that floating-point arithmetic is not exact. Since floating-point numbers are represented as digits composed of powers of 2, and fractions are negative powers of 2, a decimal fraction cannot be represented exactly.

The only solution is to understand the problem and deal with it. You can read more about floating-point truncation error here: http://en.wikipedia.org/wiki/Floating_point

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com