02-05-2009 04:07 PM
Hello
I am programming in CVI 8.5.1. I simply want to see if a number divides evenly into another. To do this I'm using fmod and wrote a small program to see if it works as I think.
int CVICALLBACK Divide (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
{
double divisor, dividend, remainder;
switch (event)
{
case EVENT_COMMIT:
GetCtrlVal(panel, PANEL_DIVIDEND, ÷nd);
GetCtrlVal(panel, PANEL_DIVISOR, &divisor);
remainder = fmod(dividend, divisor);
SetCtrlVal(panel, PANEL_REMAINDER, remainder);
break;
}
return 0;
}
This function does not respond as I expect. For example
dividend: 1.00
divisor: 0.10
The function returns 0.1 as the remainder of (dividend/divisor)
And
dividend: 0.30divisor: 0.10
returns remainder = 0.1
And
dividend: 0.40divisor: 0.10
returns remainder = 0.0
And
dividend: 0.50divisor: 0.10
returns remainder = 0.1
I do not know what to think when I check it with a calculator and the answer is not the same
Can I get an answer to
(1) why I don't get 0.00 for all the remainder for the above cases
(2) how can I compute if two number evenly divide into each other.
Thank you
Matt
02-06-2009 12:27 AM
hm, don't know, but did you check that your numeric control PANEL_REMAINDER permits displaying all values? So if you open the control panel, check if lower limit and upper limit are set properly and allow all possible results...
Wolfgang
02-06-2009 01:22 AM
you may forget my previous comment, I have tried calling this function without the help of any control;
here are some results:
fmod ( 1.0; 1.0 ) works fine (0)
fmod ( 1.0; 0.5 ) works fine (0)
fmod ( 1.0; 0.2 ) seems buggy: ( 0.2 )
fmod ( 1.0; 0.1 ) seems buggy, too ( 0.1 ), as reported by you
So it appears that you have discovered a bug...
Wolfgang
02-06-2009 02:24 AM
This item has been discussed a while ago in the forum: look at this discussion and the linked ones. Basically it seems that there is a problem given by the accuracy on floating number internal representation, that influences fmod operator. In one of the linked discussions a LabVIEW vi is described that covers this issue; the description is detailed so it should not be difficult to port this approach to CVI even without opening the VI.
Another approach could be to define a significant level of approximation (tenths, hundredths,... ?), multiply bt this factor, cast to an integer and apply integer remainder operator %