Convert decimal to int with ceil and floor - C++
Hi, I'm having a little problem of converting a decimal value to an int and either ceil it or floor it depending if the value is above .5 or not.
In C#, this is done automatically, in C++, it seems like it will floor down the value all the time.
Example code:
const double a = 0.496241;
const double b = -5.214286;
int mod = ((a * 18) + b); // results in 3.7, so i want it ceiled to 4 and not floored to 3.
If I need to manually check if the decimal value is equal or less to .5 to either ceil or floor, how do I get my hands on the decimal value in a simple manner?
Quote:Original post by NunyahJust add 0.5 before truncating to an int. E.g:
const double a = 0.496241;
const double b = -5.214286;
int mod = ((a * 18) + b); // results in 3.7, so i want it ceiled to 4 and not floored to 3.
int mod = ((a * 18) + b + 0.5);
That's a very neat solution, had I not depended on negative results.
I guess my example should have mentioned that, sorry. The value of 18, can be anything from 1 and upwards.
So if the number is 8 or 9, I should end up with -1, 6 or 7 would be -2 and so on.
Example code:
int Person::CalcModifiers(int stat)
{
/* Based on linear regression. 6 and 7 = -2, 8 and 9 = -1, 10 and 11 = 0, 12 and 13 = 1 etc 18 and 19 = 4 */
const double a = 0.496241;
const double b = -5.214286;
return int((a * stat) + b);
}
I guess my example should have mentioned that, sorry. The value of 18, can be anything from 1 and upwards.
So if the number is 8 or 9, I should end up with -1, 6 or 7 would be -2 and so on.
Example code:
int Person::CalcModifiers(int stat)
{
/* Based on linear regression. 6 and 7 = -2, 8 and 9 = -1, 10 and 11 = 0, 12 and 13 = 1 etc 18 and 19 = 4 */
const double a = 0.496241;
const double b = -5.214286;
return int((a * stat) + b);
}
this probably is not the best solution but i guess it works:
float fmod;
int mod = fmod = ((a * 18) + b);
now calculate the difference between them if it's bigger than 0.5 just add 1 to the int or substract one if you are working with negative numbers.
in case of the example: 3.7-3=0.7 which is bigger than 0.5, so 3+=1 gives 4! :)
float fmod;
int mod = fmod = ((a * 18) + b);
now calculate the difference between them if it's bigger than 0.5 just add 1 to the int or substract one if you are working with negative numbers.
in case of the example: 3.7-3=0.7 which is bigger than 0.5, so 3+=1 gives 4! :)
The following code solved my question. Probably a real kludge, so please improve with cleaner code! :)
int Person::CalcModifiers(int stat)
{
/* Based on linear regression. 7 = -2, 8 and 9 = -1, 10 and 11 = 0, 12 and 13 = 1 etc 18 and 19 = 4 */
const double a = 0.496241;
const double b = -5.214286;
double mod = ((a * stat) + b);
double dec = mod - int(mod);
if (dec < 0.5 && dec > 0)
{
return floor(mod);
}
else if(dec >= 0.5)
{
return ceil(mod);
}
else if(dec < -0.5)
{
return floor(mod);
}
else
{
return ceil(mod);
}
}
int Person::CalcModifiers(int stat)
{
/* Based on linear regression. 7 = -2, 8 and 9 = -1, 10 and 11 = 0, 12 and 13 = 1 etc 18 and 19 = 4 */
const double a = 0.496241;
const double b = -5.214286;
double mod = ((a * stat) + b);
double dec = mod - int(mod);
if (dec < 0.5 && dec > 0)
{
return floor(mod);
}
else if(dec >= 0.5)
{
return ceil(mod);
}
else if(dec < -0.5)
{
return floor(mod);
}
else
{
return ceil(mod);
}
}
If what you're really trying to do is create the mapping "6 and 7 = -2, 8 and 9 = -1, 10 and 11 = 0, 12 and 13 = 1 etc 18 and 19 = 4", then all this linear regression and rounding stuff is much too complicated. :)
Instead, *use* the behaviour of integer division in C++: if you divide those input values by 2, then the mapping becomes "3 and 3 = -2, 4 and 4 = -1, 5 and 5 = 0, etc.", and it's bleedingly obvious what to do:
If you need to handle negative inputs (which I doubt - it looks like this is for implementing some D20 system stuff, yes? :) ), things are slightly complicated, because C and C++ don't specify the rounding direction when you divide a negative value. (This is in the long established but far from fine :) tradition of leaving these kinds of things undefined so that the compiler can pick out the fastest possible translation to machine code.) But it's easily dealt with when you want to round towards zero: simply detect the sign, flip the value if it's negative, do the math, and restore the sign. When you want to be sure of rounding towards minus infinity, it's a little trickier, but still doable :)
Instead, *use* the behaviour of integer division in C++: if you divide those input values by 2, then the mapping becomes "3 and 3 = -2, 4 and 4 = -1, 5 and 5 = 0, etc.", and it's bleedingly obvious what to do:
int Person::CalcModifier(int stat) { // Just a point on function naming: I changed it to be singular, to reflect the // fact that only one modifier is being calculated. return (stat / 2) - 5;}
If you need to handle negative inputs (which I doubt - it looks like this is for implementing some D20 system stuff, yes? :) ), things are slightly complicated, because C and C++ don't specify the rounding direction when you divide a negative value. (This is in the long established but far from fine :) tradition of leaving these kinds of things undefined so that the compiler can pick out the fastest possible translation to machine code.) But it's easily dealt with when you want to round towards zero: simply detect the sign, flip the value if it's negative, do the math, and restore the sign. When you want to be sure of rounding towards minus infinity, it's a little trickier, but still doable :)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement