tags:

views:

670

answers:

4

Hi..

I want an integer to be multiples of 10,100,1000 and so on...

For eg double val = 35 then I want int 40
val = 357 then I want int val = 400
val = 245,567 then I want int val = 300,000
val = 245,567.986 then also I want int = 300,000

Is there anything in C# that can help in generating these integer

Basic logic that I can think is : Extract the first integer , add 1 to it. Count the total number of digits and add zeros (totalno -1 ).

Is there any better way ?

I want to assign these values to the chart axis. I am trying to dynamically create the axis label values based on datapoints of the charts.

A: 

Can't give you a c#-specific answer, but generally what you're looking for is log10, whatever it's called in c#. If you want to operate on number.

If this is about output, you can, indeed, operate on string, skipping/adjusting first number, etc.

Michael Krelin - hacker
+26  A: 

This should do what you want where x is the input:

        double scale = Math.Pow(10, (int)Math.Log10(x));
        int val = (int)(Math.Ceiling(x / scale) * scale);

Output:

 35          40
 357         400
 245567      300000
 245567.986  300000

If you want it to cope with negative numbers (assuming you want to round away from 0):

        double scale = (x == 0 ? 1.0 : Math.Pow(10, (int)Math.Log10(Math.Abs(x))));
        int val = (int)(Math.Ceiling(Math.Abs(x) / scale) * scale)*  Math.Sign(x);

Which gives:

-35         -40
 0           0
 35          40
 357         400
 245567      300000
 245567.986  300000
JDunkerley
too slow :( --------------
Yannick M.
yup, that's more elaborate.
Michael Krelin - hacker
Nice answer. Math wins.
Pierre-Alain Vigeant
This approach will fail however for negative values of x
Yannick M.
I am not expecting negetive values of X
ssal
Indeed but trivial to fix. Just use Math.Abs(x) in the lines above and multiply by Math.Sign(x) to get the result
JDunkerley
But the approach can easily be extended to support negative input and 0 (!) as well.
0xA3
Hey thanks.. I am using this :)
ssal
okk..I will extend for negetive values as the data keeps changing for different databases...
ssal
Can you explain de mathematic reason of (int)Math.Log10(x) please?
Daok
This finds the highest power of 10 below x. Math.Log10(x) is the inverse function of Math.Pow(10, x) (i.e. Math.Pow(10, Math.Log10(x)) = x). The (int) is just to round the result down to highest integer below it.
JDunkerley
@JDunkerley: I consider 0.0 still not handled correctly. It only works because you cast to `int` in the second line. Note that `Math.Ceiling(Math.Abs(x) / scale) * scale` evaluates to `NaN`. Of course the result is correct, but the intermediate values make no sense.
0xA3
@divo: Indeed you are correct my mistake. Will update to answer to cope more correctly with 0
JDunkerley
@ssal: Even if you are not expecting negative values of `x`, the best practice here is to implement the function to correctly handle negative values. It costs you nothing in terms of development time, nothing in terms of performance time, but could save oodles of time down the road if your requirements do change or if things don't go as expected.
Jason
A: 

This should to the trick:

// val is the value
var log = Math.Floor(Math.Log10(val));
var multiplier = Math.Pow(10, log);

var result = Math.Ceiling(val/multiplier)*multiplier;
Tor Haugen
+2  A: 

This approach should work for both positive an negative values of x:

int log = (x == 0) ? 1 : (int)(Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(x)))));
int result = (int)(((x < 0) ? Math.Floor(x / log) : Math.Ceiling(x / log)) * log);
Yannick M.