1

I am finding it hard to debug this line of code. The proper result should be 14,130 but I am getting 10597.5 instead when the input is 15 for area of a sphere. Below is the code:

// HW1, Q2
#include <iostream>
using namespace std;
int main() {

    // declare variables for radius, length and formulas.

    int user_nbr;
    double pi, sqr_area, circ_area, sphr_area;
    pi = 3.14;

    cout<<"Hi, enter an integer: "<<endl;

    // write in user data into declared variables
    cin >> user_nbr, sqr_len, circ_rad, sphr_rad;
    sqr_area = user_nbr * user_nbr;
    circ_area = pi * user_nbr * user_nbr;
    sphr_area = (4/3) * pi * user_nbr * user_nbr * user_nbr;

    // displays answers to user
    cout<<"\nThe area of a square with length "
        <<user_nbr<<" is "<<sqr_area<<". The area "
        <<"of a circle with radius "<<user_nbr
        <<" is "<<circ_area<<". Lastly, the area "
        <<"of a sphere with radius "<<user_nbr
        <<" is "<<sphr_area<<".";

return 0;
}

I am new to C++ so I am attempting to understand the operators and their workings. I know it's () */% +- in that order of precedence.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
RoiMinuit
  • 404
  • 4
  • 17
  • 4
    Did you know that "4/3" is 1, in C++? Also, what do you expect "cin >> user_nbr, sqr_len, circ_rad, sphr_rad" to do? – Sam Varshavchik Feb 09 '20 at 00:29
  • 1
    Not central to the programming issue here but still related: The area of a sphere is 4*pi*r*r. The formula you have, as fixed by the answer below, gives the volume. – nanofarad Feb 09 '20 at 00:39
  • @SamVarshavchik now that you brought it up, yes. It becomes 1 instead of 1.33 since the operation is with two integers. With your 2nd question, I expect the user input to be written into the variables to the right of the >> – RoiMinuit Feb 09 '20 at 00:45
  • @ReinstateMonica-ζ-- Thank you for the heads up; my professor asked it that way so I am going to turn it in as is. Maybe she made a mistake. – RoiMinuit Feb 09 '20 at 00:59
  • 1
    No, that's not how C++ works. That should be "cin >> user_nbr >> sqr_len >> circ_rad >> sphr_rad;". – Sam Varshavchik Feb 09 '20 at 03:44

2 Answers2

1

The result of 4/3 is an int, so it's 1, use:

sphr_area = (4.0/3.0) * pi * user_nbr * user_nbr * user_nbr;

6.5.5 Multiplicative operators 6

When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.


Note: This is often called ‘‘truncation toward zero’’.

ISO/IEC 9899:TC3

anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 1
    It is not implicitly converted, the division is just done as integer division. The result would also be `1`, not `0`. This isn't OP's only mistake either. – walnut Feb 09 '20 at 00:35
  • Yes, 4/3, 1.33, bad math... But isn't it converted, is it rounded (floored) then? how does that work? – anastaciu Feb 09 '20 at 00:37
  • 2
    @anastaciu There's not really a conversion since the division doesn't first compute 1.333... and then convert it by flooring it. The rule for division of integers directly gives 1.0. I'm not sure where this distinction actually becomes necessary, but there's a possibility that some rule in the C++ standard hinges on there not being a conversion here. – nanofarad Feb 09 '20 at 00:43
  • @ReinstateMonica-ζ-- I'm unaware of any rule in the standard that hinges on there being no "conversion here". Equally there is no requirement that there be a "conversion here". If a conversion was ever required, it would limit the ability to use hardware capabilities to do operations on integers and introduce edge cases for implementations to deal with, due to needing to account for imprecision of of floating point and produce the same results as if a conversion had occurred. – Peter Feb 09 '20 at 00:52
  • What @Peter wrote is what I found problematic in the wording "*implicitly converted*". It makes it sound as if the division is first done to give a `double` (?) result, which is then converted back to `int`. But floating point variables may potentially not represent the division result exactly, so that potentially a rounding error in the floating point math could cause a `int` result that is not equal to the result of the mathematical division result with fractional part discarded, which is what the standard requires integer division to do. – walnut Feb 09 '20 at 00:56
  • 1
    @anastaciu putting .00 behind 4 and 3 fixed the issue! Thank you! But how else would I be able to fix this issue with adding manually converting the operands? Also, the professor explicitly asked for the user input to be an integer. Lastly, by C++ rules the whole formula was supposed to convert into a double since there is at least one double in the operation, right? I just don't understand why 4/3 did not yield out 1.33 instead of 1. – RoiMinuit Feb 09 '20 at 00:56
  • 1
    @YokoKoko, You are very welcome my friend, as you can see you helped spark a discussion about integer division. – anastaciu Feb 09 '20 at 01:00
  • 1
    @YokoKoko When you want floating point math rather than integer math use floating point literals (i.e. number literals containing a dot). That is the common way of doing it. There isn't really a need for a different way. – walnut Feb 09 '20 at 01:01
  • 1
    @YokoKoko You can manually convert an `int` argument `user_input` to `double` by writing `static_cast(user_input)` instead of `user_input` in the formula. This is not needed if the other operand of the arithmetic operator is already a `double` (in that case there is an implicit conversion to `double`). It is not enough that there is a `double` *anywhere* in a sequence of arithmetic operations. Arithmetic operators are evaluated according to precedence and associativity and for each operator the operation type is calculated individually from its operands. – walnut Feb 09 '20 at 01:06
  • 2
    @YokoKoko The `/` is one such operator. Its operands are `4` and `3`, both of which have type `int` (because they do not contain a dot to make them `double`) and therefore the calculation of `/` is done in the `int` type. It doesn't matter how the result is used further in the calculation. – walnut Feb 09 '20 at 01:10
  • @walnut your last sentence is the icing on the cake! Thank you, human! – RoiMinuit Feb 09 '20 at 01:12
  • 1
    This thread has a similar discussion [What is the behavior of integer division?](https://stackoverflow.com/questions/3602827/what-is-the-behavior-of-integer-division) though it's a bit old and C related. – anastaciu Feb 09 '20 at 01:13
-1

Is this what you expect?

[cling]$ double sphr_area = 4/3;
[cling]$ sphr_area
(double) 1.0000000

Otherwise it is misuse of types, and not an order of operations issue.

Also for π you would want to use the math.h constants, if available (see https://stackoverflow.com/a/1727896)

A T
  • 13,008
  • 21
  • 97
  • 158
  • That result would only be for the 4/3; I do see what you're pointing to though. But, not what I am looking for. – RoiMinuit Feb 09 '20 at 00:47