Aiysha
asked on
subtracting negative numbers in c++
How do I subtract two negative numbers in c++. I have declared them as double
double txtlong;
double Flong;
txtlong= -91.9472
Flong= -91.92250
double longdistance;
longdistance=Flong-txtlong; <----- this line does not give the correct answer.
You forgot some semicolons
#include <iostream>
using namespace std;
int main()
{
double txtlong;
double Flong;
txtlong= -91.9472;
Flong= -91.92250;
double longdistance;
longdistance=Flong-txtlong;
cout << longdistance << endl;
}
ASKER
the correct answer is 0.0247
and i am getting -2.46999
The program is doing
91.92250-91.9472 = -2.46999
and i am getting -2.46999
The program is doing
91.92250-91.9472 = -2.46999
ASKER
The program is doing
91.92250-91.9472 = -2.46999
instead of
The program is doing
-91.92250-(-91.9472) = -2.46999
91.92250-91.9472 = -2.46999
instead of
The program is doing
-91.92250-(-91.9472) = -2.46999
If you want the absolute difference of the numbers do
longdistance=abs(Flong-txt long);
I wonder why these variables have so odd names?
longdistance=abs(Flong-txt
I wonder why these variables have so odd names?
ASKER
I am working with geological data..its subtracting the longitude of fields and finding the distance from sources.
ASKER
itsmeandnobodyelse,
subtracting the mod is a good idea, but how I preserve the sign of the greater number?
subtracting the mod is a good idea, but how I preserve the sign of the greater number?
>>>> The program is doing
>>>> 91.92250-91.9472 = -2.46999
Why should the compiler do such strange things?
Why should it convert negative input values to positive ones and why should it return negative result where a positive result is correct?
>>>> 91.92250-91.9472 = -2.46999
Why should the compiler do such strange things?
Why should it convert negative input values to positive ones and why should it return negative result where a positive result is correct?
ASKER
I was hoping you experts can help me figure this out.
I don't get the wrong answer. Verify your code, perhaps?
My code below outputs:
0.03
0.03
0.03
-0.03
My code below outputs:
0.03
0.03
0.03
-0.03
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double txtlong;
double Flong;
Flong= -91.92;
txtlong= -91.95;
double longdistance;
// -91.92 +91.95
longdistance= Flong - txtlong;
cout << longdistance << endl;
cout << std::abs(Flong - txtlong) << endl;
cout << Flong - txtlong << endl;
cout << txtlong - Flong << endl;
}
ASKER
does this have any influence on the calculation
#include "stdafx.h"
#include <iostream.h>
#include <math.h> instead of <cmath>
I am creating a .dll in c++ to be called from vb 6.0
#include "stdafx.h"
#include <iostream.h>
#include <math.h> instead of <cmath>
I am creating a .dll in c++ to be called from vb 6.0
>>>> but how I preserve the sign of the greater number?
Hmmm. Normally you would operate with either positive numbers or either negative numbers. Building the difference of a positive and a negative coordinate doesn't make so much sense, or?
But you can make you a helper sign function like
int signOfDbl(double d)
{
return (d < 0.)? -1 : 1;
}
Then
signOfDbl(FLong);
would return 1 if FLong is positive or 0.0 and -1 else.
If you know that both numbers (must) have the same sign, you could have
int sgn = signOfDbl(FLong);
and have the sign of both.
if the numbers can have different signs the bigger number always has positive sign. If you need the sign of the number which is absolute bigger than the other you can do
double x = 3.1;
double y = -5.7;
int sgn = signOfDbl(x - y); // == sign of y
Hmmm. Normally you would operate with either positive numbers or either negative numbers. Building the difference of a positive and a negative coordinate doesn't make so much sense, or?
But you can make you a helper sign function like
int signOfDbl(double d)
{
return (d < 0.)? -1 : 1;
}
Then
signOfDbl(FLong);
would return 1 if FLong is positive or 0.0 and -1 else.
If you know that both numbers (must) have the same sign, you could have
int sgn = signOfDbl(FLong);
and have the sign of both.
if the numbers can have different signs the bigger number always has positive sign. If you need the sign of the number which is absolute bigger than the other you can do
double x = 3.1;
double y = -5.7;
int sgn = signOfDbl(x - y); // == sign of y
No, it should not affect builtin C++ mathematic operations on a double.
Since your original sample was not legal C++ I am suspicious as to your actual code and would prefer to see the real code.
Since your original sample was not legal C++ I am suspicious as to your actual code and would prefer to see the real code.
>>>> does this have any influence on the calculation
No. Though you normally wouldn't use precompiled headers (stdafx.h) for a dll.
>>>> I was hoping you experts can help me figure this out.
How did you get the result of -2.46999 ?
The code you posted didn't compile because of the missing semicolons?
The code mrjoltcola posted - same as my own test code - see below - have the correct results? Could you show how you come to the wrong results?
No. Though you normally wouldn't use precompiled headers (stdafx.h) for a dll.
>>>> I was hoping you experts can help me figure this out.
How did you get the result of -2.46999 ?
The code you posted didn't compile because of the missing semicolons?
The code mrjoltcola posted - same as my own test code - see below - have the correct results? Could you show how you come to the wrong results?
int main()
{
double txtlong;
double Flong;
txtlong= -91.9472;
Flong= -91.92250;
double longdistance;
longdistance=Flong-txtlong;
// here I set a breakpoint
return 0;
}
ASKER
Following is my c++ and vb 6.0 code
// example1.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include <iostream.h>
#include <math.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
double _stdcall sum(double x , double y, double m, double n, double i)
{
double latdistance;
double longdistance;
double txtlong;
double txtlat;
double Flong;
double Flat;
double comparelong;
double comparelat;
double N_S_distance;
double E_W_distance;
double iValue;
double rValue;
Flat=x;
txtlong= n;
Flong = y;
txtlat=m;
iValue=i;
latdistance=Flat-txtlat;
longdistance=Flong-txtlong;
if (longdistance < 0.00)
{comparelong=-1.00;}
if (longdistance>0.00)
{comparelong=1.00;}
if (latdistance<0.00)
{comparelat=-1.00;}
if (latdistance>0.00)
{comparelat=1.00;}
N_S_distance=comparelong*acos(cos(((90-txtlat)*3.14159265)/180)*cos(((90-txtlat)*3.14159265)/180)+sin(((90-txtlat)*3.14159265)/180)*sin(((90-txtlat)*3.14159265)/180)*cos(((txtlong-Flong)*3.14159265)/180))*3440.65;
E_W_distance=comparelat*acos(cos(((90-txtlat)*3.14159265)/180)*cos(((90-Flat)*3.14159265)/180)+sin(((90-txtlat)*3.14159265)/180)*sin(((90-Flat)*3.14159265)/180)*cos(((Flong-Flong)*3.14159265)/180))*3440.65;
if (iValue==1.0)
{ rValue=latdistance;}
if(iValue==2.0)
{rValue=longdistance;}
if(iValue==3.0)
{rValue=N_S_distance;}
if(iValue==4.0)
{rValue=E_W_distance;}
return rValue;
}
-----------------------------------------------------------------------------------------------
Private Declare Function sum Lib "example1.dll" (ByVal x As Double, ByVal y As Double, ByVal m As Double, ByVal n As Double, ByVal p As Double) As Double
Private Sub Command1_Click()
Dim x, y, m, n, q
x = CDbl("29.890280")
m = CDbl("-91.92250")
y = CDbl("-91.9472")
n = CDbl("28.0")
q = CDbl("2.0")
Text3.Text = sum(x, y, m, n, q)
End Sub
Just a note here: make also sure that you are not printing the number in the E form
0.0247 = 2.47E-2 which with can be printed as 2.46999 if you are not careful what you print. It still does not explain the sign change though.
As the posted code is obviously not the used one, this is also probably part of the problem
0.0247 = 2.47E-2 which with can be printed as 2.46999 if you are not careful what you print. It still does not explain the sign change though.
As the posted code is obviously not the used one, this is also probably part of the problem
Aiysha: Your question has now evolved to a VB / C++ interop question. We answered your original question, and I just want to say I have nothing else to comment on regarding your VB / DLL stuff, so as not to be rude and seem like I am ignoring further comments, I am stepping out. I imagine the error is not in the plain C++. You might consider posting a new question cross-zone to Microsoft C++ and VB forums.
Or maybe itsmeandnobodyelse will see your error. Good luck! I'll check back later.
Or maybe itsmeandnobodyelse will see your error. Good luck! I'll check back later.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
itsmeandnobodyelse:
Thank you soo much for pointing out the problem. I took your advice and passed iValue as int, but vb gives me error as the function sum() cannot find its entry point.
After correcting the input values I still get
-91.9472- -91.92250 = 2.46999
instead of
-91.9472- -91.92250 = 0.024720
Do you think the compiler has problem outputting numbers less than 1?..silly question but forgive me I am very new to C++.
Thank you soo much for pointing out the problem. I took your advice and passed iValue as int, but vb gives me error as the function sum() cannot find its entry point.
After correcting the input values I still get
-91.9472- -91.92250 = 2.46999
instead of
-91.9472- -91.92250 = 0.024720
Do you think the compiler has problem outputting numbers less than 1?..silly question but forgive me I am very new to C++.
ASKER
mrjoltcola:
Thank you very much for your response. I completely understand and I am very grateful for the help you provided.
Thank you very much for your response. I completely understand and I am very grateful for the help you provided.
Put a break point in your VB code and see if CDbl is converting correctly. The decimal separator in the string is dependant of the locale settings in your system.
You should also declare the variables with explicit types
Dim x, y, m, n, q as Double
You should also declare the variables with explicit types
Dim x, y, m, n, q as Double
Changing iValue to an int is a bit of a red-herring.
Whole numbers that are 15 digits or less are represented by doubles exactly. So when you say something like "X = 2.0", it will be stored as exactly 2.0. It's when you say something like "X = 2.1" that the number might actually get stored as "2.0999999999999999" or something. But since iValue is being set to a whole number and being compared to a whole number, itsmeandnobodyelse point, while correct, isn't the issue for THIS situation.
Additionally, the reason you can't find the entry point is that you can't just simply change the declaration of a function defined in a DLL. In other words, the DLL currently has a function 'sum', and when you delcare that function for use by VB, the VB declare MUST match what is in the DLL. So the only way you can change iValue to an integer is if you change it in both the VB AND C DLL code to be an integer. And then you would have to make sure they are BOTH 16 bit integers (in VB, Integer is a 16 bit integer, in C, int can be a 16 or 32 bit integer depending upon the compiler).
To ensure the DLL function is getting called correctly, you must follow Kimpan's advice and declare all your VB variables as Double. Otherwise, they by default get declared as a variant, and you are then attempting to pass a variant to a library the want a double. And I'm not sure that VB is properly doing that for you.
So at this point, you need to change iValue back to a double, and specifically declare all your VB variables as doubles (i.e., since "sum" takes 5 doubles, you need to pass 5 doubles rather than 5 variants).
Now where itsmeandnobodyelse will be correct, the code...
x = CDbl("29.890280")
m = CDbl("-91.92250")
y = CDbl("-91.9472")
will NOT set these values to exactly the values shown. From the point of view of a floating point number they will be basically the same, but you might find that "y" actually is "91.94719999999" or something like that.
If possible, the C code should be changed to initialize rValue = 0. That way, if I'm wrong and itmeandnobodyelse's comments are causing the problem, what whould be happening is that what ever random data located at rValue is getting returned (because the if statements wouldn't be moving anything into rValue, and what ever code recently executed would have set data where rValue is located, so you could be getting the same random number over and over).
Whole numbers that are 15 digits or less are represented by doubles exactly. So when you say something like "X = 2.0", it will be stored as exactly 2.0. It's when you say something like "X = 2.1" that the number might actually get stored as "2.0999999999999999" or something. But since iValue is being set to a whole number and being compared to a whole number, itsmeandnobodyelse point, while correct, isn't the issue for THIS situation.
Additionally, the reason you can't find the entry point is that you can't just simply change the declaration of a function defined in a DLL. In other words, the DLL currently has a function 'sum', and when you delcare that function for use by VB, the VB declare MUST match what is in the DLL. So the only way you can change iValue to an integer is if you change it in both the VB AND C DLL code to be an integer. And then you would have to make sure they are BOTH 16 bit integers (in VB, Integer is a 16 bit integer, in C, int can be a 16 or 32 bit integer depending upon the compiler).
To ensure the DLL function is getting called correctly, you must follow Kimpan's advice and declare all your VB variables as Double. Otherwise, they by default get declared as a variant, and you are then attempting to pass a variant to a library the want a double. And I'm not sure that VB is properly doing that for you.
So at this point, you need to change iValue back to a double, and specifically declare all your VB variables as doubles (i.e., since "sum" takes 5 doubles, you need to pass 5 doubles rather than 5 variants).
Now where itsmeandnobodyelse will be correct, the code...
x = CDbl("29.890280")
m = CDbl("-91.92250")
y = CDbl("-91.9472")
will NOT set these values to exactly the values shown. From the point of view of a floating point number they will be basically the same, but you might find that "y" actually is "91.94719999999" or something like that.
If possible, the C code should be changed to initialize rValue = 0. That way, if I'm wrong and itmeandnobodyelse's comments are causing the problem, what whould be happening is that what ever random data located at rValue is getting returned (because the if statements wouldn't be moving anything into rValue, and what ever code recently executed would have set data where rValue is located, so you could be getting the same random number over and over).
>>>> but vb gives me error as the function sum() cannot find its entry point.
You would need to change both signatures, in C++ and VB, to have the last argument an integer.
>>>> After correcting the input values I still get
>>>> -91.9472- -91.92250 = 2.46999
Please forgive me, if I have still doubts that the input values you expect to have passed are the ones which were used for calculation.
The -91.9472 was passed as m and the -91.92250 was passed as y. As you have pairs of same quality (x, y) and (m, n), there is at least a flaw in naming if not more. Be also aware that the output of 2.46999 might be a 2.46999E-2 f not using the appropriate output formats.
>>>> Do you think the compiler has problem outputting numbers less than 1?..
I do C++ for more than 16 years. All these times I have found two or three real compiler bugs and maybe 5 or six flaws in the runtime libraries and MFC. All other cillion of errors were errors I made myself. Hence you actually must not look for a compiler bugs but simply make sure that the numbers you pass were not mixed up. BTW, if you would name the arguments similar to that they were meaning, it would simplify the issue by grades.
You would need to change both signatures, in C++ and VB, to have the last argument an integer.
>>>> After correcting the input values I still get
>>>> -91.9472- -91.92250 = 2.46999
Please forgive me, if I have still doubts that the input values you expect to have passed are the ones which were used for calculation.
The -91.9472 was passed as m and the -91.92250 was passed as y. As you have pairs of same quality (x, y) and (m, n), there is at least a flaw in naming if not more. Be also aware that the output of 2.46999 might be a 2.46999E-2 f not using the appropriate output formats.
>>>> Do you think the compiler has problem outputting numbers less than 1?..
I do C++ for more than 16 years. All these times I have found two or three real compiler bugs and maybe 5 or six flaws in the runtime libraries and MFC. All other cillion of errors were errors I made myself. Hence you actually must not look for a compiler bugs but simply make sure that the numbers you pass were not mixed up. BTW, if you would name the arguments similar to that they were meaning, it would simplify the issue by grades.
Hi,
If you need add a negative sign to the variable longdistance.
Hope it solves your problem.
Regards,
AeGIs007.
If you need add a negative sign to the variable longdistance.
Hope it solves your problem.
Regards,
AeGIs007.
long txtlong;
long Flong;
txtlong= -91.9472
Flong= -91.92250
long longdistance;
longdistance= (labs(Flong)-labs(txtlong));
ASKER
itsmeandnobodyelse and venabili helped me out, but I dont know how to split the points.
What is a negative number minus a negative number?