Ceiling Operation Gives Wrong answer - casting

`when I Run the following code it gives me answer as 16777216 but it is supposed to give 16777215 why is this so..
int d=33554431;
d=d-ceil(d/(float)2);
cout<<d<<" ";

Well, my calculator says that 33,554,431 / 2 is actually 16,777,215.5, which means that ceil(16,777,215.5) = 16,777,216 is actually correct.
Ceil rounds up to the next bigger integer, if that was unclear.

Ok, at first I misunderstood your question; the title sounds like you are asking why the Ceiling (ceil function) isn't correct.
int d=33554431;
d=d-ceil(d/(float)2);
cout<<d<<" ";
In your second line, you cast the literal 2 to a float value so the compiler also converts d to a float when it calculates d/2. Because of the internal representation, float (single precision floating point) are limited in the values that they can accurately represent. I typically assume no more than 7 digits of precision, if I need more than that, I use doubles. Anyway if you look at this link (https://en.wikipedia.org/wiki/Single-precision_floating-point_format) integers in the range [16777217,33554432] round to a multiple of 2. SO when the compiler converts d to a float it becomes 33554432. You can see that be running the following code:
int d1 = 33554431;
float f = d1;
int d2 = f;
cout << d1 << endl;
cout << f << endl;
cout << d2 << endl;
To fix your original code, try this:
int d=33554431;
d=d-ceil(d/(double)2);
cout<<d<<" ";
or
int d=33554431;
d=d-ceil(d/2.0);
cout<<d<<" ";

Related

How to set precision of a float?

For a number a = 1.263839, we can do -
float a = 1.263839
cout << fixed << setprecision(2) << a <<endl;
output :- 1.26
But what if i want set precision of a number and store it, for example-
convert 1.263839 to 1.26 without printing it.
But what if i want set precision of a number and store it
You can store the desired precision in a variable:
int precision = 2;
You can then later use this stored precision when converting the float to a string:
std::cout << std::setprecision(precision) << a;
I think OP wants to convert from 1.263839 to 1.26 without printing the number.
If this is your goal, then you first must realise, that 1.26 is not representable by most commonly used floating point representation. The closest representable 32 bit binary IEEE-754 value is 1.2599999904632568359375.
So, assuming such representation, the best that you can hope for is some value that is very close to 1.26. In best case the one I showed, but since we need to calculate the value, keep in mind that some tiny error may be involved beyond the inability to precisely represent the value (at least in theory; there is no error with your example input using the algorithm below, but the possibility of accuracy loss should always be considered with floating point math).
The calculation is as follows:
Let P bet the number of digits after decimal point that you want to round to (2 in this case).
Let D be 10P (100 in this case).
Multiply input by D
std::round to nearest integer.
Divide by D.
P.S. Sometimes you might not want to round to the nearest, but instead want std::floor or std::ceil to the precision. This is slightly trickier. Simply std::floor(val * D) / D is wrong. For example 9.70 floored to two decimals that way would become 9.69, which would be undesirable.
What you can do in this case is multiply with one magnitude of precision, round to nearest, then divide the extra magnitude and proceed:
Let P bet the number of digits after decimal point that you want to round to (2 in this case).
Let D be 10P (100 in this case).
Multiply input by D * 10
std::round to nearest integer.
Divide by 10
std::floor or std::ceil
Divide by D.
You would need to truncate it. Possibly the easiest way is to multiply it by a factor (in case of 2 decimal places, by a factor of 100), then truncate or round it, and lastly divide by the very same factor.
Now, mind you, that floating-point precision issues might occur, and that even after those operations your float might not be 1.26, but 1.26000000000003 instead.
If your goal is to store a number with a small, fixed number of digits of precision after the decimal point, you can do that by storing it as an integer with an implicit power-of-ten multiplier:
#include <stdio.h>
#include <math.h>
// Given a floating point value and the number of digits
// after the decimal-point that you want to preserve,
// returns an integer encoding of the value.
int ConvertFloatToFixedPrecision(float floatVal, int numDigitsAfterDecimalPoint)
{
return (int) roundf(floatVal*powf(10.0f, numDigitsAfterDecimalPoint));
}
// Given an integer encoding of your value (as returned
// by the above function), converts it back into a floating
// point value again.
float ConvertFixedPrecisionBackToFloat(int fixedPrecision, int numDigitsAfterDecimalPoint)
{
return ((float) fixedPrecision) / powf(10.0f, numDigitsAfterDecimalPoint);
}
int main(int argc, char ** arg)
{
const float val = 1.263839;
int fixedTwoDigits = ConvertFloatToFixedPrecision(val, 2);
printf("fixedTwoDigits=%i\n", fixedTwoDigits);
float backToFloat = ConvertFixedPrecisionBackToFloat(fixedTwoDigits, 2);
printf("backToFloat=%f\n", backToFloat);
return 0;
}
When run, the above program prints this output:
fixedTwoDigits=126
backToFloat=1.260000
If you're talking about storing exactly 1.26 in your variable, chances are you can't (there may be an off chance that exactly 1.26 works, but let's assume it doesn't for a moment) because floating point numbers don't work like that. There are always little inaccuracies because of the way computers handle floating point decimal numbers. Even if you could get 1.26 exactly, the moment you try to use it in a calculation.
That said, you can use some math and truncation tricks to get very close:
int main()
{
// our float
float a = 1.263839;
// the precision we're trying to accomplish
int precision = 100; // 3 decimal places
// because we're an int, this will keep the 126 but lose everything else
int truncated = a * precision; // multiplying by the precision ensures we keep that many digits
// convert it back to a float
// Of course, we need to ensure we're doing floating point division
float b = static_cast<float>(truncated) / precision;
cout << "a: " << a << "\n";
cout << "b: " << b << "\n";
return 0;
}
Output:
a: 1.26384
b: 1.26
Note that this is not really 1.26 here. But is is very close.
This can be demonstrated by using setprecision():
cout << "a: " << std:: setprecision(10) << a << "\n";
cout << "b: " << std:: setprecision(10) << b << "\n";
Output:
a: 1.263839006
b: 1.25999999
So again, it's not exactly 1.26, but very close, and slightly closer than you were before.
Using a stringstream would be an easy way to achieve that:
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
int main() {
stringstream s("");
s << fixed << setprecision(2) << 1.263839;
float a;
s >> a;
cout << a; //Outputs 1.26
return 0;
}

Calculate using int and output float?

//findSlope(twoPoints).exe
//finding the slope of line AB, using coordiantes of point A and B.
#include <iostream>
int main()
{
int a, b, c, d;
float answer;
std::cout << "The X coordiante of A: ";
std::cin >> a;
std::cout << "\nThe Y coordiante of A: ";
std::cin >> b;
std::cout << "\nThe X coordiante of B: ";
std::cin >> c;
std::cout << "\nThe Y coordiante of B: ";
std::cin >> d;
std::cout << "\nThe slope of line AB = " << std::endl;
answer = (b-d)/(a-c);
std::cout.setf(std::ios::fixed);
std::cout.precision(3);
std::cout << answer << std::endl;
//alternative= std::cout << fixed << setprecision(#) << answer << std::endl;
std::cout.unsetf(std::ios::fixed);
return 0;
}
I am learning C++ and I tried to code a program that calculate the slope using the coordinates of two points.
I understand that if I use float for variables I declared for the coordinates, the result of the calculation would output as float with decimals. However, I wonder if I may still use int for user input so that I can ensure the inputs are integers.
Extra question: Would it be possible to convert a float presented in the form of "#.##" to "# #/#"? More like how we do mathematics IRL.
You can use implicit conversion to double:
answer = (b-d)/(a-c*1.0);
Or explicit cast:
answer = (b-d)/(a-(float)c);
Bonuses:
for the fraction part: Converting decimal to fraction c++
Why does integer division result in an integer?
You can use int for user input, but to precisely calculate anything that contains a division operator /, you'll need to cast to floating point types.
It's usually considered a good practice in C++ to use static_cast for that (although you still may use c-style (float) syntax).
For example:
answer = static_cast<float>(b - d) / (a - c);
Here, you convert (b - d) to float and then divide it by integer, which results in a float.
Note that the following wouldn't work correctly:
answer = static_cast<float>((b - d) / (a - c));
The reason is that you first divide an int by another int and then convert the resulting int to a float.
P. S. float is really inaccurate, so I would advise to use double instead of float in all cases except where you want to write faster code that does not depend on mathematical accuracy (even though I'm not sure it would be faster on modern processors) or maintain compatibility with an existing library that uses float for some of its functions.

C++ numbers aren't rounding correctly

I am new to Stack Overflow, and programming in general. I am in a few classes for programming C++ and have come across an assignment I am having a bit of trouble with. This program is supposed to take fahrenheit and convert it to celsius. I have seen other programs, but could not find a duplicate to my particular problem. This is my code.
#include <iostream>
using namespace std;
int main()
{
int fahrenheit;
cout << "Please enter Fahrenheit degrees: ";
cin >> fahrenheit;
int celsius = 5.0 / 9 * (fahrenheit - 32.0);
cout << "Celsius: " << celsius << endl;
return 0;
}
So this is working great on 4 of the 5 tests that are run. It rounds 22.22 to 22 and 4.44 to 4 like it should, but when 0 F is put in, it rounds -17.77 to -17 instead of -18. I have been researching for about an hour and would love some help! Thank you.
Use std::round() instead of relying on the implicit conversion from double to int. Either that, or do not use conversion at all, show the temperature as a double.
EDIT: As others already pointed out, implicit conversion will not round but truncate the number instead (simply cut off everything after the decimal point).
Integers round down implicitly, as do casts to integer types.
Most likely, using a float in place of an int would give the most sane results:
#include <iostream>
using namespace std;
int main()
{
int fahrenheit;
cout << "Please enter Fahrenheit degrees: ";
cin >> fahrenheit;
float celsius = 5.0 / 9 * (fahrenheit - 32.0);
cout << "Celsius: " << celsius << endl;
return 0;
}
To get normal-looking output (fixed-point like "14.25", not scientific with e notation), pass std::fixed to cout before printing the floating point. You can also use cout.precision() to set the number of digits you would like in the output.
If for some other reason you need an int, use std::round() around the right hand of the expression.
When the compiler converts a floating point number to an integer, it doesn't round, it truncates. I.e. it simply cuts of the digits after the decimal point. So your program behaves as it is programmed to do.
int x = 3.99;
int y = std::round(3.99);
std::cout
<< "x = " << x << std::endl
<< "y = " << y << std::endl
;
-->
x = 3
y = 4
C/C++ is not doing floating point round when static_cast<int>-ing a float to an int. If you want to round, you need to call library function std::round()

How to express large numbers to two decimal places in C++ Calculator

I am trying to write a calculator in C++ that does the basic functions of /, *, -, or + and shows the answer to two decimal places (with 0.01 precision).
For example 100.1 * 100.1 should print the result as 10020.01 but instead I get -4e-171. From my understanding this is from overflow, but that's why I chose long double in the first place!
#include <iostream>
#include <iomanip>
using namespace std;
long double getUserInput()
{
cout << "Please enter a number: \n";
long double x;
cin >> x;
return x;
}
char getMathematicalOperation()
{
cout << "Please enter which operator you want "
"(add +, subtract -, multiply *, or divide /): \n";
char o;
cin >> o;
return o;
}
long double calculateResult(long double nX, char o, long double nY)
{
// note: we use the == operator to compare two values to see if they are equal
// we need to use if statements here because there's no direct way
// to convert chOperation into the appropriate operator
if (o == '+') // if user chose addition
return nX + nY; // execute this line
if (o == '-') // if user chose subtraction
return nX - nY; // execute this line
if (o == '*') // if user chose multiplication
return nX * nY; // execute this line
if (o == '/') // if user chose division
return nX / nY; // execute this line
return -1; // default "error" value in case user passed in an invalid chOperation
}
void printResult(long double x)
{
cout << "The answer is: " << setprecision(0.01) << x << "\n";
}
long double calc()
{
// Get first number from user
long double nInput1 = getUserInput();
// Get mathematical operations from user
char o = getMathematicalOperation();
// Get second number from user
long double nInput2 = getUserInput();
// Calculate result and store in temporary variable (for readability/debug-ability)
long double nResult = calculateResult(nInput1, o, nInput2);
// Print result
printResult(nResult);
return 0;
}
setprecision tells it how many decimal places you want as an int so you're actually setting it to setprecision(0) since 0.01 get truncated. In your case you want it set to 2. You should also use std::fixed or you'll get scientific numbers.
void printResult(long double x)
{
cout << "The answer is: " << std::fixed << setprecision(2) << x << "\n";
}
working example
It is not due to overflow you get the strange result. Doubles can easily hold numbers in the range you are showing.
Try to print the result without setprecision.
EDIT:
After trying
long double x = 100.1;
cout << x << endl;
I see that it doesn't work on my Windows system.
So I searched a little and found:
print long double on windows
maybe that is the explanation.
So I tried
long double x = 100.1;
cout << (double)x << endl;
which worked fine.
2nd EDIT:
Also see this link provided by Raphael
http://oldwiki.mingw.org/index.php/long%20double
The default floating point presentation switches automatically between presentation like 314.15 and 3.1e2, depending on the size of the number and the maximum number of digits it can use. With this presentation the precision is the maximum number of digits. By default it's 6.
You can either increase the maximum number of digits so that your result can be presented like 314.15, or you can force such fixed point notation by using the std::fixed manipulator. With std::fixed the precision is the number of decimals.
However, with std::fixed very large and very small numbers may be pretty unreadable.
The setprecision() manipulator specifies the number of digits after the decimal point. So, if you want 100.01 to be printed, use setprecision(2).
When you use setprecision(0.01), the value 0.01 is being converted to int, which will have a value of 0.
It wouldn't have hurt if you had actually read the documentation for setprecision() - that clearly specifies an int argument, not a floating point one.

C++, output of one digit after the decimal

I'm new in C++ and would like to get some help.
I don't understand why I'm getting an output of only one digit after the decimal on the sum below.
I have tried to solve this with no success.
int main()
{
double alt, t;
t = 4.5;
// function for calculating the altitude over time.
alt = (-0.12)*pow(t, 4) +(12.0)*pow(t, 3) -(380.0)*pow(t, 2) +(4100.0)*t +220.0;
cout << alt << endl;
return 0;
}
The default behaviour of cout is to print six significant digits of floating points. You can change that with:
cout.precision(10);
cout << alt << endl;
which gives the output:
12019.2925
which seems to be the correct solution.
You should not try to set the precision to anything higher than roughly 15, because that is about the precision limit of the double type (typically). You can use the numeric_limits<double>::digits10 from <limits> to make sure what precision you actually have.