int array with int variable multiplication gives wrong result c++ - c++

I'm learning c++ of my own, and I thought: "Where can I find some problems to solve?"... well, reading in stackoverflow I get interested in euler project, and here I am.
I'm doing the 4th problem (not asking for help BTW), but I have a very strange issue...
In this code, I want to separate a number in "digits"... that way I can say: if the first digit of the number is equal to the last, it is a palindrome number (number that can be read left to right or right to left an will be the same number... example: 90009).
All good, but the problem is when I try to divide an array element into a power...
for example:
90009/power(10,4)=9 right? (using integers of course)...
Well, code assigns the 9 to arregloDeNumero[4], and then
arregloDeNumero[4]*pow(10,4)= 89999 :O :O ??????????
it has to be 90000 right??
in addition, I put some cout<< code, if u want to run this function and see how it works in my mind :P
but my question is: is there some bad code wrote by me or is some kind of bug or lack of knowledge?
void verificarPalindromo(int x)
{
int arregloDeNumero[6];
int diferencia=0;
for (int i=5;i>=0;i--){
cout << "the number X is: " << x;
cout << "and the difference is: " << diferencia << endl;
arregloDeNumero[i]= ((x-diferencia)/pow(10,i));
cout << "array of i= " << i << "is: " << arregloDeNumero[i];
cout << " and the difference is: " << diferencia << endl;
diferencia+=(arregloDeNumero[i]*pow(10,i));
cout << "the new difference is: " << diferencia << endl;
}
}

Although your code does not contain any floating point, the pow() function returns double and there seems to be a problem in your understanding of floating point numbers. It is frequently the case that dividing floating point numbers can result in a value that is very slightly different (perhaps only one bit) from the exact result. When such a value is converted to integer it is truncated and results in the next lower integer.
You should either
a) use a strategy that is entirely implemented using integers, or
b) use floating point, but ensure that conversions to int use rounding rather than truncation.
If you have a high enough warning level, the compiler should tell you about this potential problem.
Just to be clear, I would think the problem is here:
((x-diferencia)/pow(10,i))
The result of pow() for your integer arguments will be an integer value, but because the type is double the division is also double. It's floating point division that (usually) causes the problem of slight errors. It's possible the following change might fix it.
((x-diferencia)/(int)pow(10,i))

Related

c++ print number in hexadecimal right after floor function

I've noticed some weird behaviour in c++ which i don't understand,
i'm trying to print a truncated double in a hexadecimal representation
this code output is 17 which is a decimal representation
double a = 17.123;
cout << hex << floor(a) << '\n';
while this code output is 11 and also my desirable output
double a = 17.123;
long long aASll = floor(a);
cout << hex << aASll << '\n';
as double can get really big numbers i'm afraid of wrong output while storing the truncated number in long long variable, any suggestions or improvements?
Quoting CPPreference's documentation page for std::hex (and friends)
Modifies the default numeric base for integer I/O.
This suggests that std::hex does not have any effect on floating point inputs. The best you are going to get is
cout << hex << static_cast<long long>(floor(a)) << '\n';
or a function that does the same.
uintmax_t from <cstdint> may be useful to get the largest available integer if the values are always positive. After all, what is a negative hex number?
Since a double value can easily exceed the maximum resolution of available integers, this won't cover the whole range. If the floored values exceed what can fit in an integer type, you are going to have to do the conversion by hand or use a big integer library.
Side note: std::hexfloat does something very different and does not work correctly in all compilers due to some poor wording in the current Standard that is has since been hammered out and should be corrected in the next revision.
Just write your own version of floor and have it return an integral value. For example:
long long floorAsLongLong(double d)
{
return (long long)floor(d);
}
int main() {
double a = 17.123;
cout << hex << floorAsLongLong(a) << endl;
}

Program accuracy varying by parameters

I am trying to learn how to program in C++, so I created something that allowed to you enter a minimum, and maximum parameter, and it will compute k+(k+1)+(k+2)+...+(max), and compared it to the analytical value, using the standard formula (n(n+1)/2). It seems to work fine when I try small numbers, but when, for example, trying min=4, max=4*10^5 (400,000), I get a negative result for the sum, but a positive result checking with the analytical method, even after changing the type from 'int' to 'long'. Trying other combinations, I have achieved the opposite, with the analytical method resulting in a negative sum. I suspect this is related to the fact the type int can go up to a certain number of digits, but I wanted some confirmation on that, and if it isn't, what the actual problem is. The code is provided below:
#include <iostream>
// Values are inconsistent when paramin,parammax become large.
// For example, try (parammin,parammax)=(4,400,000)
int main() {
int parammax,parammin;
std::cout << "Input a minimum, then maximum parameter to sum up to" << std::endl;
std::cin >> parammin >> parammax;
int sum=0;
for (int iter = parammin; iter <= parammax; iter++){
sum += iter;
}
std::cout << "The sum is: " << sum << std::endl;
const int analyticalmethod = (parammax*(parammax+1)-parammin*(parammin-1))/2;
std::cout << "The analytical result for the sum is,"
" via (max*(max+1)-min*(min-1))/2: "
<< analyticalmethod << std::endl;
return 0;
}
Using very large numbers without control is dangerous in C++. The basic types int, long and long long are implementation dependant, with only the following requirements:
int is at least 16 bits large
long is at least as large as int and at least 32 bits large
long long is at least as large as long and at least 64 bits large
If you think you can need larger values, you should considere a multi precision library like the excellent gmp.

C++ decimal arithmetic libraries

I'm fairly new to adding additional libraries to Visual Studio (2013) as well as the idea that floats and doubles are usually not accurate enough when dealing with certain things like money. I originally thought that BOOST::Multiprecision cpp_dec_float would solve this problem but as I tested it I noticed some unusually things and realized that I could be wrong. for example,
cpp_dec_float_50 decimal = 0.45;
double dbl = 0.45; //for comparison
cout << fixed << setprecision(50) << "boost: " << decimal << endl;
cout << "double: " << dbl << endl;
would give results like this
boost: 0.45000000000000001110223024625156540423631668090820
double: 0.45000000000000001000000000000000000000000000000000
instead of what I expected (0.45000000000000000000000000000000000000000000000000).
is this not going to be much more accurate than just using floats or doubles? If not, I'm assuming the boost library I just linked to my VS2013 has an arbitrary integer type, would this be acceptable? the only thing I don't like about using integers for such a thing is that I'd probably have to convert interest rates into integers before multiplying it with currency which would likely result in a very, very large number which may or may not cause performance issues.
(assuming BOOST isn't what I need) what are your thoughts on Intel's Decimal Floating-Point Library? I couldn't get it to work (yet) so I'm wondering if it is worth the effort. Are there any other similar libraries worth checking out?
So, you're assigning a number (that is already in floating point) to your decimal variable. So the error that you are concerned about has already been introduced.
Instead, let's assign it with a string containing the correct number:
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
int main() {
cpp_dec_float_50 decimal("0.45");
double dbl = 0.45; //for comparison
cout << fixed << setprecision(50) << "boost: " << decimal << endl;
cout << "double: " << dbl << endl;
}
Which outputs:
boost: 0.45000000000000000000000000000000000000000000000000
double: 0.45000000000000001110223024625156540423631668090820
Use Python:
import decimal
d = decimal.Decimal("0.45")
print(d)
outputs 0.45.

C++ Float Truncation & set precision logic error

I looked for a while and couldn't find an answer on here, but it seems to be a kind of weird question. I'm working with the fstream library in C++. What I'm trying to do is take data from an input file, assign it variables, and output this to both the screen and the output file. This is all for a project i'm working on that calculates the monthly payment of the car loan, which is why the variables are named the way they are.
My data file looks like this:
105670.00 12345.00 0.057 4
and essentially what is happening is I am losing everything after the decimal of the first two numbers (regardless of what i put as the decimal), but it doesn't happen to the 3rd number. additionally, when i try to setprecision(2) of the first two numbers i get a strange logic error, which i will show after my code.
my code looks like this:
#include<fstream>
#include<iomanip>
#include<iostream>
using namespace std;
int main ()
{
ifstream din; // These are my input and output files
ofstream dout;
float purchasePrice; // The first number of the input file.
float downPayment; // Second number.
float annualInterest; // Third number.
float numYears; // Last number.
// declaring the input/output files code here
din >> purchasePrice >> downPayment >> annualInterest >> numYears;
cout << purchasePrice << endl;
cout << downPayment << endl;
cout << annualInterest << endl;
cout << setprecision(2) << purchasePrice << endl;
cout << setprecision(2) << downPayment << endl;
cout << setprecison(2) << annualInterest << endl;
}
and here is my output:
105670
12345
0.057
1.1e+005
1.2e+004
0.057
I want my output to be:
105670.00
12345.00
0.057
105670.00
12345.00
0.05
Additionally, when performing any calculations, the numbers act as if they still have everything after the decimal. My question is, why are only some of the floats truncating, and why does setprecision() not work the way it is expected in this case?
Any responses are greatly appreciated, I'm sorry its such a lengthy explanation.
You also need to set the fmtflags to fixed:
std::cout << std::fixed << std::setprecision(2) << purchasePrice << "\n";
Without specifying scientific or fixed, the output mechanisms will use whatever scheme is deemed to be best. You know what's "best", and that's a fixed point scheme. For more detail, see http://en.cppreference.com/w/cpp/io/manip .
Even better is not to use floating point numbers at all when dealing with money. It is far better to use some fixed point arithmetic package.
float generally has 24 binary bits of precision which means that it can store about 6 decimal digits of precision so if your number is greater than 100000 you're not going to get any precision at all for decimal digits.
You should use double which has about 15 decimal digits of precision in this case instead of float
That answers your specific question most likely but if this is for money you probably shouldn't be using a floating format at all, as they can;t exactly represent 0.01 as a value for example, so all your calculations will be approximate and you probably don't want that when dealing with money. Generally hold the number of pence/cents/whatever in an integer and be careful :) Or even better a class specially designed for handling money values as there are often legal requirements on rounding etc.

Display a number decimal format instead as an exponential in cout

I calculated a total of floats and I got a number like 509990e-405. I'm assuming this is the short version; how can I cout this as a full number?
cout << NASATotal << endl;
is what I have now.
You can force the output to be not in scientific notation, and to have the sufficient precision to show your small number.
#include <iomanip>
// ...
long double d = 509990e-405L;
std::cout << std::fixed << std::setprecision(410) << d << std::endl;
Output:
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050999000000
If you really want this is another question.
You can write your own BigNumber class that stores the results as strings. You would have to implement all of your numeric operations and I'm guessing performance will be an issue. But it can be done, no problem -- assuming that is what you want.