Rounding decimal down

Dec 3, 2015 at 12:32pm
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 Dec 3, 2015 at 12:42pm
Dec 3, 2015 at 1:14pm
closed account (48T7M4Gy)
I do not want to floor my value
Why not? :)
Dec 3, 2015 at 1:36pm
Doesn't flooring a value round the value down to the nearest integer?
Dec 3, 2015 at 1:51pm
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/
Dec 3, 2015 at 2:03pm
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!
Dec 3, 2015 at 2:14pm
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.
Dec 3, 2015 at 2:19pm
closed account (48T7M4Gy)
This will do the same by truncating/coverting the modified number to an int
(int) 1574.8 = 1574
Dec 3, 2015 at 2:22pm
That makes sense! Thanks for your patience and help kemort!
Dec 3, 2015 at 2:25pm
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 Dec 3, 2015 at 2:37pm
Dec 3, 2015 at 2:47pm
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
Dec 3, 2015 at 2:56pm
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 Dec 3, 2015 at 3:10pm
Dec 3, 2015 at 3:00pm
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 Dec 3, 2015 at 3:24pm
Dec 3, 2015 at 3:04pm
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.
Dec 3, 2015 at 3:07pm
Another way to do it is kemort's way which works but mine didn't for some reason lol.
Dec 3, 2015 at 3:09pm
Hello cire,

Can you explain to me why my code didn't work as intended? I am confused.
Dec 3, 2015 at 3:46pm
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.