in data 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
in data 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
in data 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
in data 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 %