Rounding decimal down

I am an engineering intern and am trying to write a program that will convert metric dimensions and tolerances to imperial. When making this conversion the tolerance must be smaller than the metric. How can I round my converted tolerance down? I do not want to floor my value. This is c++ incase i needed to specify

Thank you for your time!

1
2
3
4
5
6
7
8
9
10
11
12
13
14

double conversion = 1/25.4;
double nomTol, converted;
int k;
  
cout<<"input nominal tolerance: ";
cin>>nomTol;
converted = nomTol*conversion;

cout<<"input decimal precision";
cin>>k;
cout<<fixed<<setprecision(k);
cout<<converted;
Last edited on
closed account (48T7M4Gy)
I do not want to floor my value
Why not? :)
Doesn't flooring a value round the value down to the nearest integer?
closed account (48T7M4Gy)
Yes it does 3.82 -> 3 but isn't that what you want. What are the imperial units? .001"?
http://www.cplusplus.com/reference/cmath/floor/
I'll give you an example of what I mean. Also, by imperial I mean inches - sorry about that.

Lets say that we have 4 mm and we want to convert it to inches. The math would be
4 mm * (1/25.4) = 0.15748 inches

If I want this converted number to be used as a tolerance, it has to be either 3 or 4 decimal places(shown as k in the code above). This is because machines that use these dimensions can only go down to a 4 decimal place precision before they become inaccurate.

So rather than rounding up a tolerance to ± 0.1575, I need to make the tolerance smaller ie, round the decimal place down - to ± 0.1574.

Sorry for the confusion, hope this helps!
closed account (48T7M4Gy)
No problem, that's why I asked because I had an inkling that was the issue.

What you do is convert to 1/1000's or 1/10,000's round that and then do the division by 1000 or 10000 or whatever.

So if your unit it 1/10000 multiply .15748 by 10000 = 1574.8 round down to 1574 then ... tada you have .1574" (1574/10000) which is what I gather you are looking for.
closed account (48T7M4Gy)
This will do the same by truncating/coverting the modified number to an int
(int) 1574.8 = 1574
That makes sense! Thanks for your patience and help kemort!
Hi,

there is a function called, std::fesetround from <cfenv>

Here is an example;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cfenv>

int main () {
    double runtime = 0.756247615801;

    // Set rounding direction and output with some precision:
    const auto prev_round = std::fegetround();
    std::fesetround(FE_DOWNWARD);    
    std::cout << "desired: " << std::setprecision(6) << runtime << "\n";

    // Restore previous rounding direction and output for testing:
    std::fesetround(prev_round);
    std::cout << "default: " << std::setprecision(6) << runtime << "\n";
}


output:

1
2
desired: 0.756247
default: 0.756248
Last edited on
Hi DeathLeap,

Yeah i'm having issues trying to wrap my head around re-declaring a converted tolerance as an integer to truncate, then to push it back to a double so that it can be output as a decimal.

I think this may be a simpler way to approach this problem. I'll give it a shot.

Thanks Death
I already did it for you but it's not working as intended for some reason:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cfenv>

using namespace std;

int main() 
{
	double conversion = 1 / 25.4;
	double nomTol, converted = 0;

	cout << "INPUT NOMINAL TOLERANCE ";
	cin >> nomTol;

	converted = nomTol*conversion;

	// Set rounding direction and output with some precision:
	const auto prev_round = std::fegetround();
	std::fesetround(FE_DOWNWARD);
	std::cout << "desired: " << std::setprecision(4) << converted << "\n";

	// Restore previous rounding direction and output for testing:
	std::fesetround(prev_round);
	std::cout << "default: " << std::setprecision(4) << converted << "\n";

	system("PAUSE");
	return 0;
}


output:
1
2
3
INPUT NOMINAL TOLERANCE 4
desired: 0.1575
default: 0.1575
Last edited on
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

int main()
{

	double conversion = 25.4;
	double mmTolerance = 0, inchTolerance = 0;

	cout << "Input nominal tolerance: ";
	cin >> mmTolerance;

	inchTolerance = (int)( mmTolerance / conversion * 10000 ) / 10000.0;
	cout << inchTolerance << endl;

	return 0;
}
Input nominal tolerance: 4
0.1574
Press any key to continue . . .


Sorry for changing it. I was having trouble with the shell. Now fixed. :)
Last edited on
I think this may be a simpler way to approach this problem. I'll give it a shot.

Unfortunately, the approach doesn't offer a solution. All it does is affect the way the textual representation is formatted when the value is inserted into a stream.
Another way to do it is kemort's way which works but mine didn't for some reason lol.
Hello cire,

Can you explain to me why my code didn't work as intended? I am confused.
Can you explain to me why my code didn't work as intended? I am confused.

Probably a QOI issue. I can't look right now, but I don't believe the standard requires streams to honor the rounding specified in those co-opted C functions.
Topic archived. No new replies allowed.