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.
Related
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
Whenever I load a struct into memory the memory block seems to contain ffffff before certain bytes. After closer inspection I figured this occurs exactly at 0x80 (128 in dec).
#include <Windows.h>
#include <stdio.h>
typedef struct __tagMYSTRUCT {
BYTE unused[4096];
} MYSTRUCT, *PMYSTRUCT;
int main() {
MYSTRUCT myStruct;
for (int i = 0; i < 4094; i++) {
myStruct.unused[i] = 0x00;
}
myStruct.unused[4094] = 0x7F; /* No FFFFFF prepend */
myStruct.unused[4095] = 0x80; /* FFFFFF prepend */
MYSTRUCT *p = (MYSTRUCT*)malloc(4096);
*p = myStruct;
char *read = (char*)p;
for (int i = 0; i < 4096; i++) {
printf("%02x ", read[i]);
}
free(p);
p = NULL;
read = NULL;
return 0;
}
Any one knows why this happens and / or how to 'fix' it? (I assume bytes should reach to 0xff); if I write these bytes to a file, as in, fwrite(&myStruct, sizeof(myStruct), 1, [filestream]) it doesn't include the ffffff's
Compiler used: Visual Studio 2015 Community
P.S. as stated in the title the same occurs when using VirtualAlloc
This has nothing to do with VirtualAlloc nor with malloc.
Note that the following details depend on your platform and different things might happen on different operating systems or compilers:
char is a signed type (on your platform). It has a range of -128 to 127. When you treat the number 128 as a char it wraps around and is actually stored as -128.
%02x tells printf to print an unsigned int, in hexadecimal, with at least two digits. But you are actually passing a char. The compiler will automatically convert it to an int (with the value -128), which printf will then misinterpret as an unsigned int. On your platform, -128 converted to an unsigned int will give the same value as 0xffffff80.
Yet my lectures in C++ at university began yet i got my first problems. Our task was it to implement a self made structure in C++ for floating points via the IEEE 754 standard:
Create a data structure that allows you to store a float, read its raw byte representation and its internal representation as s, e and m. Use a combination of union and bit-field-struct.
Write a program where a float number is assigned to the float part of the structure and the raw and s/e/m representation is printed. Use hexadecimal output for raw and m.
What i had so far is the following:
#include <stdio.h>
#include <math.h>
union {
struct KFloat {
//Using bit fields for our self made float. s sign, e exponent, m mantissa
//It should be unsigned because we simply use 0 and 1
unsigned int s : 1, e : 8, m : 23;
};
//One bit will be wasted for our '.'
char internal[33];
};
float calculateRealFloat(KFloat kfloat) {
if(kfloat.s == 0) {
return (1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0));
} else if (kfloat.s == 1) {
return (-1.0)*((1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0)));
}
//Error case when s is bigger 1
return 0.0;
}
int main(void) {
KFloat kf_pos = {0, 128, 1.5707963705062866};//This should be Pi (rounded) aka 3.1415927
KFloat kf_neg = {1, 128, 1.5707963705062866};//Pi negative
float f_pos = calculateRealFloat(kf_pos);
float f_neg = calculateRealFloat(kf_neg);
printf("The positive float is %f or ",f_pos);
printf("%e\n", f_pos);
printf("The negative float is %f or ",f_neg);
printf("%e", f_neg);
return 0;
}
The first error with this code is clearly that the mantissa is absolutely wrong but i have no idea how to fix this.
please reread the task:
Create a data structure that allows you to store a float,
read its raw byte representation
and its internal representation as s, e and m.
this does not mean that you should store a string
I would do this the following way:
union MyFloat
{
unsigned char rawByteDataRep[4];
unsigned int rawDataRep;
float floatRep;
struct{ // not checked this part just copied from you
unsigned s : 1;
unsigned e : 8;
unsigned m : 23;
} componentesRep;
}
but be careful!
Besides the fact that this union-conversion pattern is widely used, the C-Standard states that the result is undefined behaviour if you read another unionmember than the one that was written.
Edit:
added uint32 rep
void testMyfloat()
{
MyFloat mf;
mf.floatRep = 3.14;
printf("The float %f is assembled from sign %i magnitude 0x%08x and exponent %i and looks in memory like that 0x%08x.\n",
mf.floatRep,
(int)mf.componentesRep.s,
(unsigned int)mf.componentesRep.m,
(int)mf.componentesRep.e,
mf.componentesRep.rawDataRep);
}
Bruce Dawson has an excellent series of blog posts on floating point representation and arithmetic. The latest in the series, which has a bunch of links to previous posts that discusses this subject matter in detail, is here.
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.
Program:
void DibLaplacian8Direct(CDib sourceImg)
{
register int i,j;
int w = sourceImg.GetWidth();
int h = sourceImg.GetHeight();
CDib cpyImage = sourceImg;
BYTE** pSourceImg = sourceImg.GetPtr();
BYTE** pCpyImage = cpyImage.GetPtr();
float G;
for(j =1;j<h-1;j++)
{
for(i =1;i<w-1;i++)
{
G = -1*pCpyImage[j-1][i-1] + -1*pCpyImage[j-1][i] + (-1)*pCpyImage[j-1][i+1]+
(-1)*pCpyImage[j][i-1] + 8*pCpyImage[j][i] + (-1)*pCpyImage[j][i+1]+
-1*pCpyImage[j+1][i-1] + (-1)*pCpyImage[j+1][i] + -1*pCpyImage[j+1][i+1];
pSourceImg[j][i] = (BYTE)G;
}
}
}
warning error:
warning.. Can't coonvert from int to float..
Warning 1 warning C4819: The file contains a character that cannot be represented in the current code page (1257). Save the file in Unicode format to prevent data loss D:\2nd\imagetool\dibfilter.cpp 1 1 ImageTool
I do't understand that why its making me warning of int to float.
and for warning 1,
I am using VS 2010.. i do't know that i am getting warning in StdAfx.h include file .
Amy one can help me with this .
The first warning is due to the fact that a float has only six significant figures whereas an int can have more. If it does, then accuracy is lost.
In general, you cannot convert an integer to floating point without possible losing data. Also, you cannot convert from floating point back to integer without losing the deceimal places, so you get a warning again.
A simple minimalistic code example of the above case:
#include<iostream>
using namespace std;
int main()
{
int a=10;
int b=3;
float c;
c=a/b;
cout << c << endl;
return 0;
}
If you are sure of the data being in the range and there wont be any loss of accuracy you can use typecasting to get rid of the warning.
G = (float) (.....)
Check this for the second warning.
To get rid of the second warning you need to save the file in Unicode format.
Go to file->advanced save options and under that select the new encoding you want to save it as. UTF-8 or UNICODE codepage 1200 are the settings you want.
It is important to understand what the compiler is telling you with warning 20. The issue is that floating point numbers have only 23 bits of precision, while ints have 31. If your numbers is larger than 2^23, you will lose the low bits by storing in a float.
Now your number can never be larger than 2^23, so you are fine. Still, it is important to know what is going on here. There is a reason for that warning, and simply putting in the cast without understanding what is going on may mess you up some day.
In your specific case, I am not at all clear on why you are using a float. You are adding nine integers, none of which can be greater than 2^11. You have plenty of precision in an int to do that. Using a float is just going to slow your program down. (Probably quite a bit.)
Finally, that last cast to BYTE is worrisome. What happens if your value is out of range? Probably not what you want. For example if BYTE is unsigned, and your float ends up -3.0, you will be storing 253 as the result.