Does adding a .0 after integer have any effect on division? - c++

I took a programming test, and my teacher took points off for diving by 3 instead of 3.0 , even though it appears I get the same answer.
volu = PI*(BASE*BASE)*(HEIGHT/3);
Does the .0 even matter in a c++ program, if so why?
Thank you!
EDIT: I used doubles for PI and BASE

(For what it's worth I find the way you have it to be rather prudent.)
If HEIGHT was an integral type then it would have been absolutely essential that you wrote 3.0 rather than 3. (3.0 is a literal of type double, cf. 3 which is an int.)
Otherwise the division would have taken place in integer arithmetic, causing the result to go off.
Personally I'd remove all the redundant parentheses and write it as
PI * BASE * BASE * HEIGHT / 3;

Yes, two integers will be divided using euclidean division. Adding the .0 changes it into a normal division, because you're no longer dividing two integers but an integer and a double.

Related

Improper Double Calculations [duplicate]

Teaching myself C and finding that when I do an equation for a temp conversion it won't work unless I change the fraction to a decimal. ie,
tempC=(.555*(tempF-32)) will work but tempC=((5/9)*(tempF-32)) won't work.
Why?
According to the book "C Primer Plus" it should work as I'm using floats for both tempC and tempF.
It looks like you have integer division in the second case:
tempC=((5/9)*(tempF-32))
The 5 / 9 will get truncated to zero.
To fix that, you need to make one of them a floating-point type:
tempC=((5./9.)*(tempF-32))
When you do 5/9, 5 and 9 are both integers and integer division happens. The result of integer division is an integer and it is the quotient of the two operands. So, the quotient in case of 5/9 is 0 and since you multiply by 0, tempC comes out to be 0. In order to not have integer division, atleast one of the two operands must be float.
E.g. if you use 5.0/9 or 5/9.0 or 5.0/9.0, it will work as expected.
5/9 is an integer division not a floating point division. That's why you are getting wrong result.
Make 5 or 9 floating point variable and you will get correct answer.
Like 5.0/9 OR 5/9.0
5/9 is an integer expression, as such it gets truncated to 0. your compiler should warn you about this, else you should look into enabling warnings.
If you put 5/9 in parenthesis, this will be calculated first, and since those are two integers, it will be done by integer division and the result will be 0, before the rest of the expression is evaluated.
You can rearrange your expression so that the conversion to float occurs first:
tempC=((5/9)*(tempF-32)); → tempC=(5*(tempF-32))/9;
or of course, as the others say, use floating point constants.

float variable does not store decimal [duplicate]

This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 6 years ago.
The code I used in C++ is:
float y;
y=360/100;
cout<<y;
the output is 3.
Even, if I don't output y, and instead use it for a function like left(y), the value 3 is taken instead of 3.6. But if I define y=360.0/100, it works fine.
By the way, left() is a function included in package made by our CS prof. Left(x) changes the direction by an angle of x degrees towards left. A logo based package.
This is the way the language is defined. You divide an int by an int, so the calculation is performed resulting in an int, giving 3 (truncating, rather than rounding).
You then store 3 into a float, giving 3.0.
If you want the division performed using floats, make (at least) one of the arguments a float, e.g. 360f / 100. In this way, they other argument will be converted to a float before the division is performed.
360 / 100f will work equally well, but I think it probably make sense to make it clear as early as possible that this is a floating point calculation, rather than an integral one; that's a human consideration, rather than a technical one.
(Note that 360.0 is actually a double, although using that will work as well. The division would be performed as a double, then the result converted to a float for the assignment).
360/100 is computed in integer arithmetic before it's assigned to the float.
Reworking to 360f / 100 is my favourite way of fixing this.
Finally these days floats are for quiche eaters, girls, and folk who don't understand how modern chipsets work. Use a double type instead - which will probably be faster -, and 360.0 / 100.

Should I add a tiny amount when trying to use std::round()?

Here is a situation where a round_to_2_digits() function is rounding down when we expected it to round up. This turned out to be the case where a number cannot be represented exactly in a double. I don't remember the exact value, but say this:
double value = 1.155;
double value_rounded = round_to_2_digits( value );
The value was the output of a function, and instead of being exactly 1.155 like the code above, it actually was returning something like 1.15499999999999999. So calling std::round() on it would result in 1.15 instead of 1.16 like we thought.
Questions:
I'm thinking it may be wise to add a tiny value in round_to_2_digits() prior to calling std::round().
Is this standard practice, or acceptable? For example, adding the 0.0005 to the value being rounded.
Is there a mathematical term for this kind of "fudge factor"?
EDIT: "epsilon" was the term I was looking for.
And since the function rounds to only 2 digits after the decimal point, should I be adding 0.001? 0.005? 0.0005?
The rounding function is quite simple:
double round_to_2_decimals( double value )
{
value *= 100.0;
value = std::round(value);
value /= 100.0;
return value;
}
Step one is admitting that double may not be the right data type for your application. :-) Consider using a fixed-point type, or multiplying all of your values by 100 (or 1000, or whatever), and working with integer values.
You can't actually guarantee that adding any particular small epsilon won't give you the wrong results in some other situation. What if your value actually was 1.54999999..., and you rounded it up? Then you'd have the wrong value the other way.
The problem with your suggested solution is that at the end of it, you're still going to have a binary fraction that's not necessarily equal to the decimal value you're trying to represent. The only way to fix this is to use a representation that can exactly represent the values you want to use.
This question doesn't make a lot of sense. POSIX mandates std::round rounds half away from zero. So the result should in fact be 116 not 115. In order to actually replicate your behavior, I had to use a function that pays attention to rounding mode:
std::fesetround(FE_DOWNWARD);
std::cout << std::setprecision(20) << std::rint(1.155 * 100.0);
This was tested on GCC 5.2.0 and Clang 3.7.0.

d0 when taking roots of numbers

So in general, I understand the difference between specifying 3. and 3.0d0 with the difference being the number of digits stored by the computer. When doing arithmetic operations, I generally make sure everything is in double precision. However, I am confused about the following operations:
64^(1./3.) vs. 64^(1.0d0/3.0d0)
It took me a couple of weeks to find an error where I was assigning the output of 64^(1.0d0/3.0d0) to an integer. Because 64^(1.0d0/3.0d0) returns 3.999999, the integer got the value 3 and not 4. However, 64^(1./3.) = 4.00000. Can someone explain to me why it is wise to use 1./3. vs. 1.0d0/3.0d0 here?
The issue isn't so much single versus double precision. All floating point calculations are subject to imprecision compared to true real numbers. In assigning a real to an integer, Fortran truncates. You probably want to use the Fortran intrinsic nint.
this is a peculiar fortuitous case where the lower precision calculation gives the exact result. You can see this without the integer conversion issue:
write(*,*)4.d0-64**(1./3.),4.d0-64**(1.d0/3.d0)
0.000000000 4.440892E-016
In general this does not happen, here the double precision value is "better"
write(*,*)13.d0-2197**(1./3.),13.d0-2197**(1.d0/3.d0)
-9.5367E-7 1.77E-015
Here, since the s.p. calc comes out slightly high it gives you the correct value on integer conversion, while the d.p. result will get rounded down, hence be wrong, even though the floating point error was smaller.
So in general, no you should not consider use of single precision to be preferred.
in fact 64 and 125 seem to be the only special cases where the s.p. calc gives a perfect cube root while the d.p. calc does not.

Incorrect floating point math?

Here is a problem that has had me completely baffled for the past few hours...
I have an equation hard coded in my program:
double s2;
s2 = -(0*13)/84+6/42-0/84+24/12+(6*13)/42;
Every time i run the program, the computer spits out 3 as the answer, however doing the math by hand, i get 4. Even further, after inputting the equation into Matlab, I also get the answer 4. Whats going on here?
The only thing i can think of that is going wrong here would be round off error. However with a maximum of 5 rounding errors, coupled with using double precision math, my maximum error would be very very small so i doubt that is the problem.
Anyone able to offer any solutions?
Thanks in advance,
-Faken
You're not actually doing floating point math there, you're doing integer math, which will floor the results of divisions.
In C++, 5/4 = 1, not 1.25 - because 5 and 4 are both integers, so the result will be an integer, and thus the fractional part of the result is thrown away.
On the other hand, 5.0/4.0 will equal approx. 1.25 because at least one of 5.0 and 4.0 is a floating-point number so the result will also be floating point.
You're confusing integer division with floating point division. 3 is the correct answer with integer division. You'll get 4 if you convert those values to floating point numbers.
Some of this is being evaluated using integer arithmetic. Try adding a decimal place to your numbers, e.g. 6.0 instead 6 to tell the compiler that you don't want integer arithmetic.
s2 = -(0*13)/84+6/42-0/84+24/12+(6*13)/42;
yields 3
s2 = -(0.*13.)/84.+6./42.-0./84.+24./12.+(6.*13.)/42.;
does what you are expecting.