-
October 24th, 2024, 06:08 AM
#1
Round off or trucate double to two decimal places
Hello,
I have an issue with the converting the user input from the xml to two decimal places.
The user can input any number from the xml. But i need to consider the value only if it is double .
Lets say, I have valid range for the double number as { 6.22, 3.44, 7.8, 0, 1, 2}
My question is if the user enters 6.215 => should i round off the input to 6.22 Or should i ignore the value as not valid.
I have googled about the issues in the floating point rounding off and representation issues.
I have written sample program as follows
Code:
double precision(double f, int places)
{
double n = std::pow(10.0f, places);
return std::round(f * n) / n;
}
bool isNumeric(const std::string& str, double &d) {
try {
size_t sz(0);
d = std::stod(str, &sz);
return sz == str.size();
}
catch (const std::invalid_argument&) {
// if no conversion could be performed.
return false;
}
catch (const std::out_of_range&) {
// if the converted value would fall out of the range of the result type.
return false;
}
}
int main()
{
double value(6.55);
value = precision(value, 2);
}
The issue with the precision function is if i give 6.55 => rounded off number after the precision is not 6.55 but "6.5499999999999998" which is not what i expected !!!
Could the experts throw some useful inputs please ?
Thankyou very much
pdk
-
October 24th, 2024, 07:26 AM
#2
Re: Round off or trucate double to two decimal places
https://en.wikipedia.org/wiki/Floating-point_arithmetic
Floating point numbers are approximations.
Not every possible decimal fraction has an exact floating point representation.
https://www.omnicalculator.com/other/floating-point
Pasting in 6.55 gets you this information.
Single-precision (32-bit) floating point
6.55 converted to 32-bit floating point is
010000001101000110011001100110102 (40D1999AH) with:
Sign: 0
Exponent: 10000001
Fraction: 10100011001100110011010
The real value of this representation is 6.55000019073486328.
The machine error resulting from this conversion is 1.90734863281250000000000000000e-7.
Double-precision (64-bit) floating point
6.55 converted to 64-bit floating point is
01000000000110100011001100110011001100110011001100110011001100112 (401A333333333400H) with:
Sign: 0
Exponent: 10000000001
Fraction: 1010001100110011001100110011001100110011001100110011
The real value of this representation is 6.54999999999999982.
The machine error resulting from this conversion is 1.77635683940025056328542382157e-16.
As you can see in the fractional part of both formats, it's just "0011" repeating forever.
Except it can't be forever on a finite machine.
Presumably, you only care that it's say "6.55" when you come to save it in a file or show it to the user?
-
October 24th, 2024, 08:42 AM
#3
Re: Round off or trucate double to two decimal places
How many decimal places is really just for display/output purposes. It isn't to do with how floating point numbers are stored. If you want to display a number with only 2 dp then there are ways with std::format etc to do this. But this isn't for how the numbers are stored.
if the user enters 6.215 => should i round off the input to 6.22 Or should i ignore the value as not valid.
Whether the input is valid is not is for you to decide. If you really, really want to try to round a floating point number to a certain number of decimals then consider:
https://stackoverflow.com/questions/...-in-c-language
https://stackoverflow.com/questions/...mal-point-in-c
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
October 24th, 2024, 11:22 AM
#4
Re: Round off or trucate double to two decimal places
@Salem and kaud, Thanks a lot for the help.
In my case, I need to take a input from the user, which is in text format and convert to double.
The value can only take the distict values as per requirement . ie { 6.22, 3.44, 7.8, 0, 1, 2}
So I guess, i donot need to round off user provided numbers. If user provides a string like lets say doesnot exactly match, I just ignore those inputs. So I donot need to truncate/round/ceil the input.
Like in my case, even if the user provides a string, 6.221, shouldnot be converted, just ignored.
I guess, I am thinking another way of handling, as Im writiing here. (Instead of converting the user string to double.). May be I should have just converted the valid list of doubles to strings. and check if the user input matches one of the strings in the valid list.
-
October 24th, 2024, 12:33 PM
#5
Re: Round off or trucate double to two decimal places
> The value can only take the distict values as per requirement . ie { 6.22, 3.44, 7.8, 0, 1, 2}
So perhaps don't treat them as floats, but as fixed point numbers instead.
Internally, you would store these as
622, 344, 780, 0, 100, 200
You would read 6.22 as a pair of integers, separated by a dot.
Code:
class frac {
int int_part;
int frac_part;
public:
friend ostream & operator << (ostream &out, const frac &c);
friend istream & operator >> (istream &in, frac &c);
};
https://www.geeksforgeeks.org/overlo...n-operators-c/
The somewhat interesting part will be handling the optional dot.
-
October 25th, 2024, 03:28 AM
#6
Re: Round off or trucate double to two decimal places
@Salem : Thankyou very much for the inputs. It really helps me a lot, to get inputs from knowledgable people.
@kaud: Thankyou very much for the help and comments..
-
October 25th, 2024, 03:33 AM
#7
Re: Round off or trucate double to two decimal places
If the entered numbers must be exactly these stated numbers, then enter as string and compare as string (ignore any leading/trailing spaces). As salem_c mentions above, you might want to treat these as fixed point numbers. Once validated then check for the presence of a '.' If not found then add .0 to the end and extract as integer1 char integer2. Multiple integer1 by 100 and add integer2. Then all arithmetic, comparison etc are done as integer. When you want to display etc then just reverse the process.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|