1

I am under s situation where i find modulo of 2.0 %0.1 which as result of double variable returns "0.09999" not "0".

My code to do this is:

    var distanceFactor = slider.Value % step; //This do not return 0 when Value=2.0 and step=0.1
    if (distanceFactor != 0)
    {
        slider.Value -= distanceFactor;
    }    
    elseif(distanceFactor == 0)
    {
       //do something here
    }           
    txtblUnits.Text = Math.Round(slider.Value, 1).ToString();

How to obtain the control in elseif condition when Value=2.0 and step=0.1 ?

Sss
  • 1,519
  • 8
  • 37
  • 67
  • 1
    You can check if distanceFactor-step is smaller than a predefined epsilon value. By the way modulo on doubles is not a great idea... – qqbenq Jul 03 '14 at 10:06
  • 1
    Modulus shouldn't be used with not integer values as, in mathematics, is an integer operator. You are trying to do mod(2, 0.1) and that is the same than doing mod(20,1) – Kaitiff Jul 03 '14 at 10:12
  • Look at the provided 'duplicate question' link, there is the equation for what takes place with a modulo operator ... just do it that long-hand way: ... `double a, b, r; a = 120; b = .05; r = a - Math.floor(a / b) * b;` – Mashton Jul 04 '14 at 14:19

4 Answers4

3

Modulo % has no sense with floating number. You should multiply and cast it to int before applying the operator.

var distanceFactor = ((int) (slider.Value * 10D)) % (int) (step * 10D);
Perfect28
  • 11,089
  • 3
  • 25
  • 45
  • i cannot do that because this slider.Value is obtained by moving slider and it's in double and if i make it decimal then it will avoid the small drag of slider progree which is printed on textblock. – Sss Jul 03 '14 at 12:31
1

You can round the distance factor to 0 decimal in the if condition, like this

if (Math.Round(distanceFactor,0) != 0)
{
    slider.Value -= distanceFactor;
}    
else
{
   //do something here
}
Kiran Hegde
  • 3,651
  • 1
  • 16
  • 14
1

Double will not work for modulus operator so Using modulus with floating point numbers is never a good idea so better to use decimal instead.

decimal slider = 2.0M, step = 0.1M;
var distanceFactor = slider % step; //This will return 0 when Value=2.0 and step=0.1
if (distanceFactor != 0)
{
    slider -= distanceFactor;
}
else if (distanceFactor == 0)
{
    //do something here
}
txtblUnits.Text = Math.Round(slider, 1).ToString();

txtblUnits.Text will have 2.0

Vishal Suthar
  • 17,013
  • 3
  • 59
  • 105
  • slider id uielement so its value is always double. we are not assigning manually it is obtained by draging the slider. – Sss Jul 03 '14 at 11:36
  • Then simply cast it to decimal as `decimal slider = (decimal)slider.Value;` – Vishal Suthar Jul 03 '14 at 11:47
  • i cannot do that because this slider.Value is obtained by moving slider and it's in double and if i make it decimal then it will avoid the small drag of slider progree which is printed on textblock. – Sss Jul 03 '14 at 12:05
1

As I commented on your post, in order to work with modulus operator correctly, try to do something like this:

string valueDecimalsString = (slider.Value - Math.Floor(slider.Value)).ToString();

int valueDecimals = valueDecimalsString.Substring(valueDecimalsString.IndexOf('.') + 1).Length;

//The same with step

int decimals = (valueDecimals > stepDecimals) ? valueDecimals : stepDecimals;

int value = (int)(slider.Value * Math.Pow(10, decimals))

//the same with step

var distanceFactor = value % stepValue; 
waka
  • 3,362
  • 9
  • 35
  • 54
Kaitiff
  • 416
  • 3
  • 9
  • could you please also explain in words your logic ? thanskj – Sss Jul 03 '14 at 11:32
  • For sure :) As modulus is and integer operator, what we do here is to get the same division with only integer numbers. We multiply each number by 10 to the nth power, being n the max of decimals in those numbers. – Kaitiff Jul 03 '14 at 11:49