round() function produces a strange number - c++

I declare double variables t and tau, and assign them values 1 and 0.00001
This line of code produces 536870912 in the console. What can be the reason?
printf("%i\n",round(t/(tau*double(2))));
By the way, I write code in a C++ compiler, but practically it's C.

round returns a double. Printing it with %i is undefined behaviour.
Use %f for printing double:
printf("%f\n",round(t/(tau*double(2))));

Use %lf instead of %i and remove double line it is unnecessary because you are already defined variables as double.
#include <stdio.h>
#include <math.h>
int main()
{
double t = 1, tau = 0.00001;
printf("%lf\n", round(t/(tau*2)));
return 0;
}
Output -: 50000.000000
If you want 50000 only you can edit your code into like this
double t = 1, tau = 0.00001;
int answer;
answer = round(t/(tau*2));
printf("%i\n", answer);
Output -: 50000

Related

How to round off the totalcost (double) to nearest inetegrs

I have tried to search similar questions all over the net but non was useful for me.
The nearest I got to was "If the number before the .5 is odd round up, if even round down 13.5 turns into 14 but 12.5 turns into 12".
Coming to the question:
I simply need to calculate the total amount after a meal with the formula;
total amount = mealamount+ mealamount*tip% + mealamount *tax%
I came up with this piece of code (rough only)
#include<iostream>
#include<math.h>
#include <iomanip>
using namespace std;
int main () {
double mealCost;
double total=0;
double tipp,taxx=0;
cin>>mealCost;
int tip;
cin>>tip;
tipp=(tip*mealCost)/100;
int tax;
cin>>tax;
taxx=(tax*mealCost)/100;
total=mealCost+tipp+taxx;
cout << fixed << showpoint;
cout << setprecision(2);
cout<<total<<endl;
return 0;
}
but with the set of inputs of 10.75(mealamonut), 17(tip%),5 (tax %).
the value am getting is 12.50
if I use
int totalSum = std::round(total);
its getting converted to 12
but my requirement is 13 .
How to acheive that ?
I cannot find any duplicate question to this if exists
please mention.
There are multiple ways to convert doubles to integers. You have multiple kinds of round. Check them here, which are std::round, std::lround, std::llround.
On the other hand, if what you want to do is not rounding, but elimination of fractions into one direction, then you have std::ceil that goes always higher, and std::floor, that always goes lower.
Remember to include <cmath>, not <math.h>. The latter is for C, not C++
You achieve your goal by using std::ceil() and std::floor() which is defined under cmath header file.
You are trying to always round up so you would need to use the ceil() function. Ceil is short for ceiling and there is also a floor function. Ceiling is up, floor is down, here is a c snippet to try out.
#include <stdio.h> /* printf */
#include <math.h> /* ceil */
int main ()
{
printf ( "ceil of 2.3 is %.1f\n", ceil(2.3) );
printf ( "ceil of 3.8 is %.1f\n", ceil(3.8) );
printf ( "ceil of -2.3 is %.1f\n", ceil(-2.3) );
printf ( "ceil of -3.8 is %.1f\n", ceil(-3.8) );
return 0;
}
for rounding to nearest integer math.h has nearbyint
printf ( "nearbyint (2.3) = %.1f\n", nearbyint(2.3) );
printf ( "nearbyint (3.8) = %.1f\n", nearbyint(3.8) );
Output:
nearbyint (2.3) = 2.0
nearbyint (3.8) = 4.0
Or if you want to break the default rounding behavior when .5
int totalSum= (total - floor(total) ) >= 0.5 ? ceil(total) : floor(total);
1) 10.75 + 17*10.75/100 + 5*10.75/100 = 13.115 ... how comes I can't get 12.50?
2) How do you know it's 12.50, how do you check value of result? (it may be only 12.4999..., so when it is formatted to two decimal places, it will become 12.50) Make sure you do check the actual real value (ideally in debugger or dump memory content in bytes and reconstruct the value by hand), not some string formatted intermediate.
3) this is not some production code, right? Amounts are not calculated with doubles in real financial software, as doubles are not accurate enough and you would run into all kind of hard problems with rounding to VAT, etc. If this is some real thing, you are not up to the task, ask for help some professional.
Answer:
std::round should normally do what you need. If it's ending as 12, then it's because the value is less than 12.5.
If rounded to two decimal places it shows as 12.50, you are hitting one of those "all kind of hard problems" of real financial software.
Then you should create your own round using string representation, like this example (not handling negative numbers and reinventing wheel probably):
#include <iostream>
#include <string>
/**
* Rounds floating point value in std::string type.
* Works only for positive values, and without "+" sign!
* ie. regexp ~\d*\.?\d*~ formatting.
* For malformed input the output is undefined (but should not crash).
**/
std::string financialRound(const std::string & amount) {
const size_t dotPos = amount.find_first_of('.');
if (std::string::npos == dotPos) return amount; // no decimals found
// copy whole part into temporary result
std::string result = (0 < dotPos) ? amount.substr(0, dotPos) : "0";
const size_t firstDecimalPos = dotPos + 1;
// see if there is 5 to 9 digit after dot
if (amount.size() <= firstDecimalPos) return result; // no char
const char firstDecimal = amount.at(firstDecimalPos);
if (firstDecimal < '5' || '9' < firstDecimal) return result; //not 5-9
// add 1 to the result
int patchPos = (int)result.size();
while (0 <= --patchPos) {
++result.at(patchPos);
if ('9'+1 == result.at(patchPos)) result.at(patchPos) = '0';
else break;
}
// check if additional 1 is required (add overflow)
if (-1 == patchPos) result.insert(result.begin(), '1');
return result;
}
void tryValue(const std::string & amount) {
printf("\"%s\" is rounded to \"%s\"\n", amount.c_str(), financialRound(amount).c_str());
}
int main()
{
printf("Trying normal values...\n");
tryValue("12.50");
tryValue("12.49");
tryValue(".49");
tryValue(".50");
tryValue("9.49");
tryValue("9.50");
printf("Missing decimals...\n");
tryValue("12");
tryValue("12.");
printf("Malformed...\n");
tryValue("");
tryValue("a.4");
tryValue("a.5");
tryValue("12..");
}
live demo on cpp.sh

Brute-force equation solving

I'm writing a program that uses brute-force to solve an equation. Unfortunately, I seem to have an error in my code somewhere, as my program stops at search = 0.19999. Here is the code:
#include <iostream>
#include <cmath>
#include <vector>
#define min -4.0
#define max 6.5
using namespace std;
double fx (double x){
long double result = cos(2*x)-0.4*x;
double scale = 0.00001;
double value = (int)(result / scale) * scale;
return value;
}
int sign (double a){
if(a<0) return -1;
if(a==0) return 0;
else return 1;
}
int main(){
vector <double> results;
double step, interval, start, end, search;
interval=(fabs(min)+fabs(max))/50;
step=0.00001;
start=min;
end=min+interval;
search=start;
while(end <= max){
if(sign(start) != sign(end)){
search=start;
while(search < end){
if(fx(search) == 0) results.push_back(search);
search=search+step;
}
}
start=end;
end=start + interval;
}
for(int i=0; i<results.size(); i++){
cout << results[i] << endl;
}
}
I've been looking at it for quite some time now and I still can't find the error in the code.
The program should check if there is a root in each given interval and, if yes, check every possibility in that interval. If it finds a root, it should push it into the results vector.
I know you already found the answer but I just spotted a problem while trying to find the bug. On line 37 you make the following comparison:
if(fx(search) == 0)
Since your fx function returns double. It's generally not advisable to test using the equal operator when dealing with double precision float numbers. Your result will probably never be exactly 0, then this test will never return true. I think you should use comparison using a maximum error margin, like this:
double maximum_error = 0.005;
if(abs(fx(search)) < maximum_error)
I think that would do the trick in your case. You may find more information on this link
Even if it's working right now, micro changes in your input numbers, CPU architecture or even compiler flags may break your program. It's highly dangerous to compare doubles in C++ like that, even though it's legal to do so.
I've just made a run through the code again and found the error.
if(sign(start) != sign(end))
was the culprit. There will be a root if the values of f(x) for start and end have different signs. Instead, I wrote that the if the signs of start and end are different, there will be a root. Sorry for the fuss.

why printf output zero for a non-zero double?

I have a piece of code:
Under Windows MSVC 2012
#include <stdio.h>
#include <string.h>
namespace myname{
double var = 42;
}
extern "C" double _ZN6myname3varE = 10.0;
int main(){
printf("%d\n", _ZN6myname3varE);
return 0;
}
The output is 0. But I think the output should be 10. Could you help explain why?
Answer for "But I want to know why 0 is output? How this happen?".
double is 64-bit and int is 32-bit. When double is truncated to int (because of using %d), only first 4 bytes stored in the memory location of double is taken into the int value.
Here, value of double _ZN6myname3varE is 10.0, which is 0x4024000000000000 in hex and stored as 00000000 00002440 in memory (little endian). So, when truncated to int, only 4 byte LSB is taken which is obviously zero.
printf("%d\n", _ZN6myname3varE);
%d should be changed to %f, which prints type double
But there's another problem: name mangling. When I tested the program in gcc, it shows an error:
Error: symbol `_ZN6myname3varE' is already defined
The problem is the name _ZN6myname3varE is a reserved identifier in C++ because it begins with underscore and an uppercase letter.

How to print a double value that is just less than another double value?

Actually I am working on range expression in c++. So what I want is if I have any expression like
x<1
Then my
double getMax(...);
should return a double value that is just before 1.000 (double precision) on a number line.
I tried doing this
double getMax(double& a)
{
return (a-numeric_limits<double>::min());
}
But I am still getting same value as a in return statement.
I think C++ is converting it to nearest double in cout statement.
int main()
{
double a = 32;
cout<<scientific<<getMax(a)<<endl;
return 0;
}
output:
3.200000e+001
First of all, you need to ensure that you actually print sufficiently many digits to ensure all representable values of double are displayed. You can do this as follows (make sure you #include <iomanip> for this):
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl;
Secondly, numeric_limits<>::min is not appropriate for this. If your starting value is 1.0, you can use numeric_limits<double>::epsilon, which is the smallest difference from 1.0 that is representable.
However, in your code example, the starting value is 32. Epsilon does not necessarily work for that. Calculating the right epsilon in this case is difficult.
However, if you can use C++11(*), there is a function in the cmath header that does what you need std::nextafter:
#include <iostream>
#include <limits>
#include <iomanip>
#include <cmath>
double getMax(double a)
{
return std::nextafter(a,std::numeric_limits<double>::lowest());
}
int main()
{
double a = 32;
std::cout << std::scientific
<< std::setprecision(std::numeric_limits<double>::max_digits10)
<< getMax(a)
<< std::endl;
return 0;
}
I've also put it on liveworkspace.
To explain:
double nextafter(double from, double to);
returns the next representable value of from in the direction of to. So I specified std::numeric_limits<double>::lowest() in my call to ensure you get the next representable value less than the argument.
(*)See Tony D's comment below. You may have access to nextafter() without C++11.
I think you've got the right idea.
Check out Setting the precision of a double without using stream (ios_base::precision) not so much for the question, but for the examples they give of using precision. You might want to try something like printing with a precision of 53.
The way I usually see "close to but not quite" involves setting a difference threshold (typically called epsilon). In that case, you wouldn't use a getMax function, but have an epsilon used in your usage of less than. (You could do a class with the epsilon value and operator overloading. I tend to avoid operator overloading like a plague.)
Basically, you'd need:
bool lessThanEpsilon(double number, double lessThan, double epsilon)
{
return (lessThan - number >= epsilon);
}
There are other varieties, of course. Equals would check if Math.abs(number - equals) < epsilon

scanf not taking in long double

i have problem with scanf not reading long double in the code below:
(please excuse my poor English)
#include <iostream>
#include <cstdlib>
#include <math.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
long double a,b,c,ha,hb,hc,ma,cosa,r,l,res,area;
for (int i=0;i<n;i++)
{
scanf("%Lf %Lf %Lf %Lf",&a,&ha,&hb,&hc);//this is where the problem lies,
//i need to read 4 long double a,ha,hb,hc
printf("%Lf %Lf %Lf %Lf\n",a,ha,hb,hc);//but it returned wrong answer so
//i used printf to check, ps: the code works with float but not with double or
//long double
ha*=3;hb*=3;hc*=3;
c=(a*ha)/hc; b=(a*ha)/hb;
ma=sqrt(0.5*b*b+0.5*c*c-0.25*a*a);
cosa=ha/ma;
r=(2*ma)/3;
l=b*(b-sqrt(a*a-hb*hb))/ha;
res=sqrt(l*l+r*r-2*cosa*l*r);
area=a*ha/2;
printf("%.3Lf %.3Lf\n",area,res);
}
system("PAUSE");
return 0;}
}
here's the input:
2
3.0 0.8660254038 0.8660254038 0.8660254038
657.8256599140 151.6154399062 213.5392629932 139.4878846649
and here what's show in the command line:
2
3.0 0.8660254038 0.8660254038 0.8660254038
3.000000 -4824911833695204400000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000.000000 284622047019579100000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000.0
00000 0.866025
-2.000 0.000
657.8256599140 151.6154399062 213.5392629932 139.4878846649
657.825660 -0.000000 28969688850499604000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000.000000 213.539263
-2.000 0.000
Press any key to continue . . .
I want to know why scanf won't take in long double in the code and how to fix it.
Thanks in advance!
Dev-c++ uses MinGW, which uses the gcc compiler and the Microsoft runtime library. Unfortunately, those components disagree on the underlying type to be used for long double (64 vs. 80 or 96 bits, I think). Windows assumes long double is the same size as double; gcc makes long double bigger.
Either choice is valid, but the combination results in a broken C and C++ implementation.
If you don't need the extra range and precision, you can read into a double and store into a long double.
Otherwise, you can write or borrow a custom string to long double converter, or just use a different implementation.
EDIT
More details:
Microsoft's own compiler and runtime library are consistent in treating long double as 64 bits, the same size as double. The language standard permits this (it requires long double to be at least as wide as double, but places the same requirements on both), but it does seem odd that it doesn't take advantage of the x86's 80-bit floating-point hardware.
gcc on x86 treats long double as 96 bits (sizeof (long double) == 12). I think only 80 of those bits are significant; the extra 16 bits are for alignment purposes.
MinGW uses gcc as its compiler, but uses Microsoft's runtime library. For most language features, this works fine, but the mismatch for long double means that you can do computations with long double, but you can't pass long double values (or pointers to them) to the runtime library. It's a bug in MinGW.
There are workarounds within MinGW. You can define the macro __USE_MINGW_ANSI_STDIO, either by passing -D__USE_MINGW_ANSI_STDIO on the gcc command line or by adding a line
#define __USE_MINGW_ANSI_STDIO
to your source files. (It has to be defined before #include <stdio.h>.) A commenter, paulsm4, says that the -ansi and -posix options cause MinGW to use its own conforming library (I have no reason to doubt this, but I'm not currently able to confirm it). Or you can call __mingw_printf() directly.
Assuming you're on Windows, Cygwin might be a good alternative (it uses gcc, but it doesn't use Microsoft's runtime library). Or you can use long double internally, but double for I/O.
You are a lucky lucky man. This won't solve the general problem of long double on MinGW, but I'll explain what is happening to your problem. Now, in a far far day when you'll be able to upvote, I want your upvote. :-) (but I don't want this to be marked as the correct response. It's the response to what you need, but not to what you asked (the general problem in your title scanf not taking in long double) ).
First, the solution: use float. Use %f in scanf/printf. The results comes perfectly equal to the ones given as the solution in your site. As a sidenote, if you want to printf with some decimals, do as it's showed in the last printf: %.10f will print 10 decimals after the decimal separator.
Second: why you had a problem with doubles: the res=sqrt() calculates a square root. Using floats, l*l+r*r-2*cosa*l*r == 0.0, using doubles it's -1.0781242565371940e-010, so something near zero BUT NEGATIVE!!! So the sqrt(-something) is NaN (Not a Number) a special value of double/float. You can check if a number is NaN by doing res != res. This because NaN != NaN (but note that this isn't guaranteed by older C standards, but in many compilers on Intel platform do it. http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html). And this explains why the printf printed something like -1.#IO.
You can avoid most of your conversion problems by actually using C++ instead of using legacy C-functions:
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
long double a = 0.0;
long double ha = 0.0;
long double hb = 0.0;
long double hc = 0.0;
int n = 0;
std::cout << "Enter Count: ";
std::cin >> n;
for (int i = 0; i < n; i++)
{
std::cout << "Enter A, Ha, Hb, Hc: ";
std::cin >> a >> ha >> hb >> hc;
std::cout.precision(10);
std::cout << "You Entered: "
<< a << " " << ha << " " << hb << " " << hc << std::endl;
ha *= 3;
hb *= 3;
hc *= 3;
long double c = (a * ha) / hc;
long double b = (a * ha) / hb;
long double ma = static_cast<long double>(std::sqrt(0.5 * b * b + 0.5 * c * c - 0.25 * a * a));
long double cosa = ha / ma;
long double r = (2 * ma) / 3;
long double l = b * (b - static_cast<long double>(std::sqrt(a * a - hb * hb))) / ha;
long double res = static_cast<long double>(std::sqrt(l * l + r * r - 2 * cosa * l * r));
long double area = a * ha / 2.0;
std::cout << "Area = " << area << std::endl;
}
return 0;
}
Don't know if this is of use to you but you could have a look at it.
long long int XDTOI(long double VALUE)
{
union
{
long double DWHOLE;
struct
{
unsigned int DMANTISSALO:32;
unsigned int DMANTISSAHI:32;
unsigned int DEXPONENT:15;
unsigned int DNEGATIVE:1;
unsigned int DEMPTY:16;
} DSPLIT;
} DKEY;
union
{
unsigned long long int WHOLE;
struct
{
unsigned int ARRAY[2];
} SPLIT;
} KEY;
int SIGNBIT,RSHIFT;
unsigned long long int BIGNUMBER;
long long int ACTUAL;
DKEY.DWHOLE=VALUE; SIGNBIT=DKEY.DSPLIT.DNEGATIVE;
RSHIFT=(63-(DKEY.DSPLIT.DEXPONENT-16383));
KEY.SPLIT.ARRAY[0]=DKEY.DSPLIT.DMANTISSALO;
KEY.SPLIT.ARRAY[1]=DKEY.DSPLIT.DMANTISSAHI;
BIGNUMBER=KEY.WHOLE;
BIGNUMBER>>=RSHIFT;
ACTUAL=((long long int)(BIGNUMBER));
if(SIGNBIT==1) ACTUAL=(-ACTUAL);
return ACTUAL;
}
Sadly enough, long double has faulty printing in GCC/Windows. However, you can guarantee that long double still does higher precision calculations in the background when you're doing arithmetic and trigonometry, because it would store at least 80 or 96 bits.
Therefore, I recommend this workaround for various things:
Use scanf on doubles, but cast them to long doubles after. You don't need precision in input parsing, anyway.
double x;
scanf("%lf", &x); // no biggie
long double y = x;
Make sure you use long double versions of functions in the <math.h> library. The normal ones will just cast your long double to double, so the higher precision will become useless.
long double sy = sqrtl(y); // not sqrt
long double ay = 2.0L * acosl(y); // note the L-suffix in the constant
To print your long double, just cast them back to double and use "%lf". Double can have at most 15 significant digits so it is more than enough. Of course, if it's not enough, you ought to switch to Linux's GCC.
printf("%.15lf\n", (double) y);
Most programs actually don't need the extra digits for the output. The thing is, even the early digits lose their precision at the slightest use of sqrt or trig functions. THEREFORE, it's OK to keep the double at least just for printing, but what's important is that you still use long double for the rough calculations to not lose the precision you worked hard to invest.