Round off a double while maintaining the trailing zero
This is a printing poblem:
double d = 1.5;
System.out.println(String.format("%.2f", d)); // 1.50
How to round double values but keep trailing zeros
You can create a formatter like this example:
int numDigitsAfterPoint = 5;
double num = 1.25d;
string result = num.ToString("0." + new string('0', numDigitsAfterPoint));
or (more easily)
string result = num.ToString("F" + numDigitsAfterPoint);
As a sidenote, ToString
uses the MidpointRounding.AwayFromZero
instead of the MidpointRounding.ToEven
(also called Banker's Rounding). As an example:
var x1 = 1.25.ToString("F1");
var x2 = 1.35.ToString("F1");
var x3 = Math.Round(1.25, 1).ToString();
var x4 = Math.Round(1.35, 1).ToString();
These will produce different result (because Math.Round
normally uses MidpointRounding.ToEven
)
And note that internally ToString()
seems to do some "magic" before rounding digits. For doubles, if you ask him less than 15 digits, I think it rounds to 15 digits first and then rounds to the right number of digits. See here https://ideone.com/ZBEis9
Rounding a number in Python but keeping ending zeros
As you are talking about trailing zeros, this is a question about representation as string,
you can use
>>> "%.2f" % round(2606.89579999999, 2)
'2606.90'
Or use modern style with format
function:
>>> '{:.2f}'.format(round(2606.89579999999, 2))
'2606.90'
and remove point with replace
or translate
(_
refers to result of previous command in python console):
>>> _.translate(None, '.')
'260690'
Note that rounding is not needed here, as .2f
format applyies the same rounding:
>>> "%.2f" % 2606.89579999999
'2606.90'
But as you mentioned excel, you probably would opt to roll your own rounding function, or use decimal, as float.round
can lead to strange results due to float representation:
>>> round(2.675, 2)
2.67
>>> round(2606.89579999999, 2)
2606.89
With decimal use quantize:
>>> from decimal import *
>>> x = Decimal('2606.8950000000001')
# Decimal('2606.8950000000001')
>>> '{}'.format(x.quantize(Decimal('.01'), rounding=ROUND_HALF_EVEN))
'2606.90'
That, for your original task, becomes:
>>> x = Decimal('2606.8950000000001')
>>> int((x*100).quantize(1, rounding=ROUND_HALF_EVEN))
260690
And the reason of strange rounding comes to the front with Decimal
:
>>> x = Decimal(2606.8950000000001)
# Decimal('2606.89499999999998181010596454143524169921875') # internal float repr
DecimalFormat - Format decimal to preserve variable amount of trailing zeros
"Preserve" trailing zeros?
A double
value doesn't know how many trailing zeroes you want to see. It is just a number, and 1.00
and 1.000
are the same number, i.e. the number 1
. What you are asking cannot be done with a double
value.
Now, BigDecimal
does remember the number of trailing zeroes, so if you want to print a BigDecimal
value, retaining the scale of the number, but ensuring it never prints in scientific notation, don't use a DecimalFormat
, but instead use toPlainString()
:
Returns a string representation of this
BigDecimal
without an exponent field.
UPDATE
If you want to print a double
value with as many decimal fraction digits as needed (i.e. no trailing zeroes), and want to make sure it never prints in scientific notation, use a DecimalFormat
with very high MaximumIntegerDigits
and very high setMaximumFractionDigits
.
"Very high" means values exceeding the range of a double
, so 999
is a good "round" number, though 330
would be high enough.
Test
DecimalFormat fmt = new DecimalFormat("0");
fmt.setMaximumIntegerDigits(330);
fmt.setMaximumFractionDigits(330);
System.out.println("0.0123400 = " + 0.0123400 + " = " + fmt.format(0.0123400));
System.out.println("123400.00 = " + 123400.00 + " = " + fmt.format(123400.00));
System.out.println("NaN = " + Double.NaN + " = " + fmt.format(Double.NaN));
System.out.println("-INFINITY = " + Double.NEGATIVE_INFINITY + " = " + fmt.format(Double.NEGATIVE_INFINITY));
System.out.println("+INFINITY = " + Double.POSITIVE_INFINITY + " = " + fmt.format(Double.POSITIVE_INFINITY));
System.out.println("MIN_NORMAL = " + Double.MIN_NORMAL + " = " + fmt.format(Double.MIN_NORMAL));
System.out.println("MIN_VALUE = " + Double.MIN_VALUE + " = " + fmt.format(Double.MIN_VALUE));
System.out.println("MAX_VALUE = " + Double.MAX_VALUE + " = " + fmt.format(Double.MAX_VALUE));
Output
0.0123400 = 0.01234 = 0.01234
123400.00 = 123400.0 = 123400
NaN = NaN = �
-INFINITY = -Infinity = -∞
+INFINITY = Infinity = ∞
MIN_NORMAL = 2.2250738585072014E-308 = 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072014
MIN_VALUE = 4.9E-324 = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049
MAX_VALUE = 1.7976931348623157E308 = 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
How to round a number and make it show zeros?
We can use format
format(round(a), nsmall = 2)
#[1] "14.00"
As @arvi1000 mentioned in the comments, we may need to specify the digits
in round
format(round(a, digits=2), nsmall = 2)
data
a <- 14.0034
Avoid trailing zeroes in printf()
This can't be done with the normal printf
format specifiers. The closest you could get would be:
printf("%.6g", 359.013); // 359.013
printf("%.6g", 359.01); // 359.01
but the ".6" is the total numeric width so
printf("%.6g", 3.01357); // 3.01357
breaks it.
What you can do is to sprintf("%.20g")
the number to a string buffer then manipulate the string to only have N characters past the decimal point.
Assuming your number is in the variable num, the following function will remove all but the first N
decimals, then strip off the trailing zeros (and decimal point if they were all zeros).
char str[50];
sprintf (str,"%.20g",num); // Make the number.
morphNumericString (str, 3);
: :
void morphNumericString (char *s, int n) {
char *p;
int count;
p = strchr (s,'.'); // Find decimal point, if any.
if (p != NULL) {
count = n; // Adjust for more or less decimals.
while (count >= 0) { // Maximum decimals allowed.
count--;
if (*p == '\0') // If there's less than desired.
break;
p++; // Next character.
}
*p-- = '\0'; // Truncate string.
while (*p == '0') // Remove trailing zeros.
*p-- = '\0';
if (*p == '.') { // If all decimals were zeros, remove ".".
*p = '\0';
}
}
}
If you're not happy with the truncation aspect (which would turn 0.12399
into 0.123
rather than rounding it to 0.124
), you can actually use the rounding facilities already provided by printf
. You just need to analyse the number before-hand to dynamically create the widths, then use those to turn the number into a string:
#include <stdio.h>
void nDecimals (char *s, double d, int n) {
int sz; double d2;
// Allow for negative.
d2 = (d >= 0) ? d : -d;
sz = (d >= 0) ? 0 : 1;
// Add one for each whole digit (0.xx special case).
if (d2 < 1) sz++;
while (d2 >= 1) { d2 /= 10.0; sz++; }
// Adjust for decimal point and fractionals.
sz += 1 + n;
// Create format string then use it.
sprintf (s, "%*.*f", sz, n, d);
}
int main (void) {
char str[50];
double num[] = { 40, 359.01335, -359.00999,
359.01, 3.01357, 0.111111111, 1.1223344 };
for (int i = 0; i < sizeof(num)/sizeof(*num); i++) {
nDecimals (str, num[i], 3);
printf ("%30.20f -> %s\n", num[i], str);
}
return 0;
}
The whole point of nDecimals()
in this case is to correctly work out the field widths, then format the number using a format string based on that. The test harness main()
shows this in action:
40.00000000000000000000 -> 40.000
359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.010
359.00999999999999090505 -> 359.010
3.01357000000000008200 -> 3.014
0.11111111099999999852 -> 0.111
1.12233439999999995429 -> 1.122
Once you have the correctly rounded value, you can once again pass that to morphNumericString()
to remove trailing zeros by simply changing:
nDecimals (str, num[i], 3);
into:
nDecimals (str, num[i], 3);
morphNumericString (str, 3);
(or calling morphNumericString
at the end of nDecimals
but, in that case, I'd probably just combine the two into one function), and you end up with:
40.00000000000000000000 -> 40
359.01335000000000263753 -> 359.013
-359.00999000000001615263 -> -359.01
359.00999999999999090505 -> 359.01
3.01357000000000008200 -> 3.014
0.11111111099999999852 -> 0.111
1.12233439999999995429 -> 1.122
Math.Round not keeping the trailing zero
1.4
is the same as 1.40
- you just want to display it differently. Use a format string when calling ToString
- like value.ToString("0.00")
Keeping trailing zeros
If this is for printing purposes, sprintf
is what you are after:
> sprintf("%.3f", round(5.2,3))
[1] "5.200"
See ?sprintf
for formatting details.
Print float/double without trailing zeros?
Use snprintf
to print to a temporary buffer then remove the trailing '0'
characters manually. There is no other way that's both correct and reasonably easy to implement.
Math.Round, keep decimal place
Numbers don't have any conception of zeroes after a decimal point.
You're actually asking how to convert the number into a string with extra zeroes:
(2.301).ToString("0.00") // "2.30"
See numeric format strings for more detail.
In particular, the 0
specifier will round away from zero.
Related Topics
Log File Is Created But File Is Empty
Delete Everything After Part of a String
How to Append a Query Parameter to an Existing Url
How to Store Original Date/Time Without Timezone Calculation to Mongodb
How to Convert a Byte to Its Binary String Representation
Java Input Validation for Number Range and Numeric Values Only With Counter
How to Check If an Integer Is in a Given Range
How to Sort by Two Fields in Java and Specify Sort Direction
How to Stop the Items Duplication in Recyclerview Android
Reading Data from Nested Json Object Using Java
Error: Could Not Find or Load Main Class in Intellij Ide
How to Use a Regex to Search Backwards Effectively
Multiple Queries Executed in Java in Single Statement
How to Return a Custom Object from a Spring Data JPA Group by Query
Replacing Double Backslashes With Single Backslash
Cannot Find Element Using Selenium Webdriver
Handling the Null Value from a Resultset
Beanutils Copyproperties API to Ignore Null and Specific Propertie