Round a decimal to the first decimal position that is not zero
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
I want to shorten a number to the first decimal position that is not null. The Decimal places behind should be rounded.
Examples:
0.001 -> 0.001
0.00367 -> 0.004
0.00337 -> 0.003
0.000000564 -> 0.0000006
0.00000432907543029 -> 0.000004
Currently I have the following procedure:
if (value < (decimal) 0.01)
value = Math.Round(value, 4);
Note:
- numbers will always be positive
- the number of significant digits will always be 1
- values larger 0.01 will always be rounded to two decimal places, hence the if < 0.01
As you can see from the examples above, a rounding to 4 Decimal places might not be enough and the value might vary greatly.
c# math decimal rounding
add a comment |Â
up vote
7
down vote
favorite
I want to shorten a number to the first decimal position that is not null. The Decimal places behind should be rounded.
Examples:
0.001 -> 0.001
0.00367 -> 0.004
0.00337 -> 0.003
0.000000564 -> 0.0000006
0.00000432907543029 -> 0.000004
Currently I have the following procedure:
if (value < (decimal) 0.01)
value = Math.Round(value, 4);
Note:
- numbers will always be positive
- the number of significant digits will always be 1
- values larger 0.01 will always be rounded to two decimal places, hence the if < 0.01
As you can see from the examples above, a rounding to 4 Decimal places might not be enough and the value might vary greatly.
c# math decimal rounding
3
Have a look here: round-a-double-to-x-significant-figures
– Aaron Hayman
49 mins ago
1
@AaronHayman: This isdecimal
rather thandouble
, and the number of significant digits isn't necessarily known - I suspect the OP doesn't want to round 123.456 to 100 for example. (Although we'll see...)
– Jon Skeet
48 mins ago
What do you want to do for values that aren't between -1 and 1? For example, what would the result for 123.456 be?
– Jon Skeet
47 mins ago
The number of significant figures is surely one, from the description. I didn't say the link is the answer, but it does provides useful information to solving the problem
– Aaron Hayman
44 mins ago
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
I want to shorten a number to the first decimal position that is not null. The Decimal places behind should be rounded.
Examples:
0.001 -> 0.001
0.00367 -> 0.004
0.00337 -> 0.003
0.000000564 -> 0.0000006
0.00000432907543029 -> 0.000004
Currently I have the following procedure:
if (value < (decimal) 0.01)
value = Math.Round(value, 4);
Note:
- numbers will always be positive
- the number of significant digits will always be 1
- values larger 0.01 will always be rounded to two decimal places, hence the if < 0.01
As you can see from the examples above, a rounding to 4 Decimal places might not be enough and the value might vary greatly.
c# math decimal rounding
I want to shorten a number to the first decimal position that is not null. The Decimal places behind should be rounded.
Examples:
0.001 -> 0.001
0.00367 -> 0.004
0.00337 -> 0.003
0.000000564 -> 0.0000006
0.00000432907543029 -> 0.000004
Currently I have the following procedure:
if (value < (decimal) 0.01)
value = Math.Round(value, 4);
Note:
- numbers will always be positive
- the number of significant digits will always be 1
- values larger 0.01 will always be rounded to two decimal places, hence the if < 0.01
As you can see from the examples above, a rounding to 4 Decimal places might not be enough and the value might vary greatly.
c# math decimal rounding
c# math decimal rounding
edited 27 mins ago
Chris
23k35981
23k35981
asked 55 mins ago


julian bechtold
856
856
3
Have a look here: round-a-double-to-x-significant-figures
– Aaron Hayman
49 mins ago
1
@AaronHayman: This isdecimal
rather thandouble
, and the number of significant digits isn't necessarily known - I suspect the OP doesn't want to round 123.456 to 100 for example. (Although we'll see...)
– Jon Skeet
48 mins ago
What do you want to do for values that aren't between -1 and 1? For example, what would the result for 123.456 be?
– Jon Skeet
47 mins ago
The number of significant figures is surely one, from the description. I didn't say the link is the answer, but it does provides useful information to solving the problem
– Aaron Hayman
44 mins ago
add a comment |Â
3
Have a look here: round-a-double-to-x-significant-figures
– Aaron Hayman
49 mins ago
1
@AaronHayman: This isdecimal
rather thandouble
, and the number of significant digits isn't necessarily known - I suspect the OP doesn't want to round 123.456 to 100 for example. (Although we'll see...)
– Jon Skeet
48 mins ago
What do you want to do for values that aren't between -1 and 1? For example, what would the result for 123.456 be?
– Jon Skeet
47 mins ago
The number of significant figures is surely one, from the description. I didn't say the link is the answer, but it does provides useful information to solving the problem
– Aaron Hayman
44 mins ago
3
3
Have a look here: round-a-double-to-x-significant-figures
– Aaron Hayman
49 mins ago
Have a look here: round-a-double-to-x-significant-figures
– Aaron Hayman
49 mins ago
1
1
@AaronHayman: This is
decimal
rather than double
, and the number of significant digits isn't necessarily known - I suspect the OP doesn't want to round 123.456 to 100 for example. (Although we'll see...)– Jon Skeet
48 mins ago
@AaronHayman: This is
decimal
rather than double
, and the number of significant digits isn't necessarily known - I suspect the OP doesn't want to round 123.456 to 100 for example. (Although we'll see...)– Jon Skeet
48 mins ago
What do you want to do for values that aren't between -1 and 1? For example, what would the result for 123.456 be?
– Jon Skeet
47 mins ago
What do you want to do for values that aren't between -1 and 1? For example, what would the result for 123.456 be?
– Jon Skeet
47 mins ago
The number of significant figures is surely one, from the description. I didn't say the link is the answer, but it does provides useful information to solving the problem
– Aaron Hayman
44 mins ago
The number of significant figures is surely one, from the description. I didn't say the link is the answer, but it does provides useful information to solving the problem
– Aaron Hayman
44 mins ago
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
10
down vote
accepted
You can try to declare precision
and use a loop to get first precision value, then use Math.Round
static decimal GetValue(decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
I would write an extehnsion method for this function.
public static class FloatExtension
public static decimal ByFirstPrecision(this decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
then use like
decimal input = 0.00001;
input.ByFirstPrecision();
c# online
Result
(-0.001m).ByFirstPrecision() -0.001
(-0.00367m).ByFirstPrecision() -0.004
(0.000000564m).ByFirstPrecision() 0.0000006
(0.00000432907543029m).ByFirstPrecision() 0.000004
Tank you, works beautiful!
– julian bechtold
34 mins ago
1
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
1
Math.Abs(val)<1?
– Access Denied
20 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
add a comment |Â
up vote
1
down vote
var value = 0.000000564;
int cnt = 0;
bool hitNum = false;
var tempVal = value;
while (!hitNum)
if(tempVal > 1)
hitNum = true;
else
tempVal *= 10;
cnt++;
var newValue = (decimal)Math.Round(value, cnt);
Look at other answer ;-)
– Tim Schmelter
31 mins ago
add a comment |Â
up vote
0
down vote
Something like that ?
public decimal SpecialRound(decimal value)
int posDot = value.ToString().IndexOf('.'); // Maybe use something about cultural (in Fr it's ",")
if(posDot == -1)
return value;
int posFirstNumber = value.ToString().IndexOfAny(new char[9] '1', '2', '3', '4', '5', '6', '7', '8', '9', posDot);
return Math.Round(value, posFirstNumber);
add a comment |Â
up vote
0
down vote
Another approach
decimal RoundToFirstNonNullDecimal(decimal value)
var nullDecimals = value.ToString().Split('.').LastOrDefault()?.TakeWhile(c => c == '0').Count();
return !nullDecimals.HasValue
Result
Console.WriteLine(RoundToFirstNonNullDecimal(0.001m)); 0.001
Console.WriteLine(RoundToFirstNonNullDecimal(0.00367m)); 0.004
Console.WriteLine(RoundToFirstNonNullDecimal(0.000000564m)); 0.0000006
Console.WriteLine(RoundToFirstNonNullDecimal(0.00000432907543029m)); 0.000004
Console.WriteLine(RoundToFirstNonNullDecimal(0.12m)); 0.12
Console.WriteLine(RoundToFirstNonNullDecimal(1.232m)); 1.232
Console.WriteLine(RoundToFirstNonNullDecimal(7)); 7
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
10
down vote
accepted
You can try to declare precision
and use a loop to get first precision value, then use Math.Round
static decimal GetValue(decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
I would write an extehnsion method for this function.
public static class FloatExtension
public static decimal ByFirstPrecision(this decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
then use like
decimal input = 0.00001;
input.ByFirstPrecision();
c# online
Result
(-0.001m).ByFirstPrecision() -0.001
(-0.00367m).ByFirstPrecision() -0.004
(0.000000564m).ByFirstPrecision() 0.0000006
(0.00000432907543029m).ByFirstPrecision() 0.000004
Tank you, works beautiful!
– julian bechtold
34 mins ago
1
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
1
Math.Abs(val)<1?
– Access Denied
20 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
add a comment |Â
up vote
10
down vote
accepted
You can try to declare precision
and use a loop to get first precision value, then use Math.Round
static decimal GetValue(decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
I would write an extehnsion method for this function.
public static class FloatExtension
public static decimal ByFirstPrecision(this decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
then use like
decimal input = 0.00001;
input.ByFirstPrecision();
c# online
Result
(-0.001m).ByFirstPrecision() -0.001
(-0.00367m).ByFirstPrecision() -0.004
(0.000000564m).ByFirstPrecision() 0.0000006
(0.00000432907543029m).ByFirstPrecision() 0.000004
Tank you, works beautiful!
– julian bechtold
34 mins ago
1
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
1
Math.Abs(val)<1?
– Access Denied
20 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
add a comment |Â
up vote
10
down vote
accepted
up vote
10
down vote
accepted
You can try to declare precision
and use a loop to get first precision value, then use Math.Round
static decimal GetValue(decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
I would write an extehnsion method for this function.
public static class FloatExtension
public static decimal ByFirstPrecision(this decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
then use like
decimal input = 0.00001;
input.ByFirstPrecision();
c# online
Result
(-0.001m).ByFirstPrecision() -0.001
(-0.00367m).ByFirstPrecision() -0.004
(0.000000564m).ByFirstPrecision() 0.0000006
(0.00000432907543029m).ByFirstPrecision() 0.000004
You can try to declare precision
and use a loop to get first precision value, then use Math.Round
static decimal GetValue(decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
I would write an extehnsion method for this function.
public static class FloatExtension
public static decimal ByFirstPrecision(this decimal input)
int precision = 0;
var val = input;
while (Math.Abs(val) < 1)
val *= 10;
precision++;
return Math.Round(input, precision);
then use like
decimal input = 0.00001;
input.ByFirstPrecision();
c# online
Result
(-0.001m).ByFirstPrecision() -0.001
(-0.00367m).ByFirstPrecision() -0.004
(0.000000564m).ByFirstPrecision() 0.0000006
(0.00000432907543029m).ByFirstPrecision() 0.000004
edited 10 mins ago
answered 40 mins ago
D-Shih
17.1k51127
17.1k51127
Tank you, works beautiful!
– julian bechtold
34 mins ago
1
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
1
Math.Abs(val)<1?
– Access Denied
20 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
add a comment |Â
Tank you, works beautiful!
– julian bechtold
34 mins ago
1
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
1
Math.Abs(val)<1?
– Access Denied
20 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
Tank you, works beautiful!
– julian bechtold
34 mins ago
Tank you, works beautiful!
– julian bechtold
34 mins ago
1
1
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
Note that this would require tweaking for negative values.
– Jon Skeet
30 mins ago
1
1
Math.Abs(val)<1?
– Access Denied
20 mins ago
Math.Abs(val)<1?
– Access Denied
20 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@JonSkeet Thank for your point out:)
– D-Shih
18 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
@AccessDenied Yes I think just compare absolute value
– D-Shih
17 mins ago
add a comment |Â
up vote
1
down vote
var value = 0.000000564;
int cnt = 0;
bool hitNum = false;
var tempVal = value;
while (!hitNum)
if(tempVal > 1)
hitNum = true;
else
tempVal *= 10;
cnt++;
var newValue = (decimal)Math.Round(value, cnt);
Look at other answer ;-)
– Tim Schmelter
31 mins ago
add a comment |Â
up vote
1
down vote
var value = 0.000000564;
int cnt = 0;
bool hitNum = false;
var tempVal = value;
while (!hitNum)
if(tempVal > 1)
hitNum = true;
else
tempVal *= 10;
cnt++;
var newValue = (decimal)Math.Round(value, cnt);
Look at other answer ;-)
– Tim Schmelter
31 mins ago
add a comment |Â
up vote
1
down vote
up vote
1
down vote
var value = 0.000000564;
int cnt = 0;
bool hitNum = false;
var tempVal = value;
while (!hitNum)
if(tempVal > 1)
hitNum = true;
else
tempVal *= 10;
cnt++;
var newValue = (decimal)Math.Round(value, cnt);
var value = 0.000000564;
int cnt = 0;
bool hitNum = false;
var tempVal = value;
while (!hitNum)
if(tempVal > 1)
hitNum = true;
else
tempVal *= 10;
cnt++;
var newValue = (decimal)Math.Round(value, cnt);
answered 34 mins ago
ManishM
25715
25715
Look at other answer ;-)
– Tim Schmelter
31 mins ago
add a comment |Â
Look at other answer ;-)
– Tim Schmelter
31 mins ago
Look at other answer ;-)
– Tim Schmelter
31 mins ago
Look at other answer ;-)
– Tim Schmelter
31 mins ago
add a comment |Â
up vote
0
down vote
Something like that ?
public decimal SpecialRound(decimal value)
int posDot = value.ToString().IndexOf('.'); // Maybe use something about cultural (in Fr it's ",")
if(posDot == -1)
return value;
int posFirstNumber = value.ToString().IndexOfAny(new char[9] '1', '2', '3', '4', '5', '6', '7', '8', '9', posDot);
return Math.Round(value, posFirstNumber);
add a comment |Â
up vote
0
down vote
Something like that ?
public decimal SpecialRound(decimal value)
int posDot = value.ToString().IndexOf('.'); // Maybe use something about cultural (in Fr it's ",")
if(posDot == -1)
return value;
int posFirstNumber = value.ToString().IndexOfAny(new char[9] '1', '2', '3', '4', '5', '6', '7', '8', '9', posDot);
return Math.Round(value, posFirstNumber);
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Something like that ?
public decimal SpecialRound(decimal value)
int posDot = value.ToString().IndexOf('.'); // Maybe use something about cultural (in Fr it's ",")
if(posDot == -1)
return value;
int posFirstNumber = value.ToString().IndexOfAny(new char[9] '1', '2', '3', '4', '5', '6', '7', '8', '9', posDot);
return Math.Round(value, posFirstNumber);
Something like that ?
public decimal SpecialRound(decimal value)
int posDot = value.ToString().IndexOf('.'); // Maybe use something about cultural (in Fr it's ",")
if(posDot == -1)
return value;
int posFirstNumber = value.ToString().IndexOfAny(new char[9] '1', '2', '3', '4', '5', '6', '7', '8', '9', posDot);
return Math.Round(value, posFirstNumber);
answered 37 mins ago
Benjamin K
5818
5818
add a comment |Â
add a comment |Â
up vote
0
down vote
Another approach
decimal RoundToFirstNonNullDecimal(decimal value)
var nullDecimals = value.ToString().Split('.').LastOrDefault()?.TakeWhile(c => c == '0').Count();
return !nullDecimals.HasValue
Result
Console.WriteLine(RoundToFirstNonNullDecimal(0.001m)); 0.001
Console.WriteLine(RoundToFirstNonNullDecimal(0.00367m)); 0.004
Console.WriteLine(RoundToFirstNonNullDecimal(0.000000564m)); 0.0000006
Console.WriteLine(RoundToFirstNonNullDecimal(0.00000432907543029m)); 0.000004
Console.WriteLine(RoundToFirstNonNullDecimal(0.12m)); 0.12
Console.WriteLine(RoundToFirstNonNullDecimal(1.232m)); 1.232
Console.WriteLine(RoundToFirstNonNullDecimal(7)); 7
add a comment |Â
up vote
0
down vote
Another approach
decimal RoundToFirstNonNullDecimal(decimal value)
var nullDecimals = value.ToString().Split('.').LastOrDefault()?.TakeWhile(c => c == '0').Count();
return !nullDecimals.HasValue
Result
Console.WriteLine(RoundToFirstNonNullDecimal(0.001m)); 0.001
Console.WriteLine(RoundToFirstNonNullDecimal(0.00367m)); 0.004
Console.WriteLine(RoundToFirstNonNullDecimal(0.000000564m)); 0.0000006
Console.WriteLine(RoundToFirstNonNullDecimal(0.00000432907543029m)); 0.000004
Console.WriteLine(RoundToFirstNonNullDecimal(0.12m)); 0.12
Console.WriteLine(RoundToFirstNonNullDecimal(1.232m)); 1.232
Console.WriteLine(RoundToFirstNonNullDecimal(7)); 7
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Another approach
decimal RoundToFirstNonNullDecimal(decimal value)
var nullDecimals = value.ToString().Split('.').LastOrDefault()?.TakeWhile(c => c == '0').Count();
return !nullDecimals.HasValue
Result
Console.WriteLine(RoundToFirstNonNullDecimal(0.001m)); 0.001
Console.WriteLine(RoundToFirstNonNullDecimal(0.00367m)); 0.004
Console.WriteLine(RoundToFirstNonNullDecimal(0.000000564m)); 0.0000006
Console.WriteLine(RoundToFirstNonNullDecimal(0.00000432907543029m)); 0.000004
Console.WriteLine(RoundToFirstNonNullDecimal(0.12m)); 0.12
Console.WriteLine(RoundToFirstNonNullDecimal(1.232m)); 1.232
Console.WriteLine(RoundToFirstNonNullDecimal(7)); 7
Another approach
decimal RoundToFirstNonNullDecimal(decimal value)
var nullDecimals = value.ToString().Split('.').LastOrDefault()?.TakeWhile(c => c == '0').Count();
return !nullDecimals.HasValue
Result
Console.WriteLine(RoundToFirstNonNullDecimal(0.001m)); 0.001
Console.WriteLine(RoundToFirstNonNullDecimal(0.00367m)); 0.004
Console.WriteLine(RoundToFirstNonNullDecimal(0.000000564m)); 0.0000006
Console.WriteLine(RoundToFirstNonNullDecimal(0.00000432907543029m)); 0.000004
Console.WriteLine(RoundToFirstNonNullDecimal(0.12m)); 0.12
Console.WriteLine(RoundToFirstNonNullDecimal(1.232m)); 1.232
Console.WriteLine(RoundToFirstNonNullDecimal(7)); 7
answered 12 mins ago


crazy_p
424
424
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52440913%2fround-a-decimal-to-the-first-decimal-position-that-is-not-zero%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
Have a look here: round-a-double-to-x-significant-figures
– Aaron Hayman
49 mins ago
1
@AaronHayman: This is
decimal
rather thandouble
, and the number of significant digits isn't necessarily known - I suspect the OP doesn't want to round 123.456 to 100 for example. (Although we'll see...)– Jon Skeet
48 mins ago
What do you want to do for values that aren't between -1 and 1? For example, what would the result for 123.456 be?
– Jon Skeet
47 mins ago
The number of significant figures is surely one, from the description. I didn't say the link is the answer, but it does provides useful information to solving the problem
– Aaron Hayman
44 mins ago