Why does this print only 0? - c

New to C, I've been trying to convert a hex input with this code. The input argv[1] I've been giving it is 0xabcd123. It has only given me 0 outputs. I have also tried using atoi as well as varying the types of outputs. Why does it only print 0? Here is the code, thanks
#include <stdio.h>
#include <stdlib.h>
typedef union{
double num;
float f;
} U;
int main(int argc, char*argv[])
{
U u;
u.num = strtod(argv[1], NULL);
printf("%e\n", u.f);
return 0;
}
result is platform dependent!

I believe its returning 0 on one system because of byte order. when you write to the value as a double but then read it as a float, you may be reading the top or bottom half of the double, depending on the architecture. on one system it's the empty top half of the double, on another its the bottom half which contains value.
either way, with a union, you should never expect to write any value as one type, and read back as another and get reliable results. as you have discovered :) unions aren't magic type converters, they simply allow you to save space when you know you have one type of value at a time.

num is declared as int. So printf("%d", u.num) or double num

First, please kindly reformat your code so that everyone can read it easily.
Second, the type of your u.num is double, so utilize %f or %lf instead of %d
Third, as shown in this codepad http://codepad.org/JSSJEKOn, your code is correct and it must obviously print the expected result. So I think that the error is not here but somewhere else in your source file. Please give us more information

Related

convert double to a printf's %g-like string with minimal length without losing any precision

I want to print double to C string with sufficient precision to recover the original number, but with the minimal length of the output string.
I can try something like this which maintains the precision. But the output string is too long.
What is an efficient way (better than trial and error as in the discussion) to return the minimal length string?
#include <stdio.h>
int main() {
printf("%1.*e\n", __DBL_DECIMAL_DIG__ - 1, 1.); // print 1.0000000000000000e+00. I want just "1."
printf("%1.*e\n", __DBL_DECIMAL_DIG__ - 1, 1.00000001); // print 1.0000000099999999e+00. I want just "1.00000001"
return 0;
}
The string representation is not necessarily the same as the original double. The string has to be of the minimal length.
Only the printf's %g like string format is allowed. printf's %a is not what I am looking for.
Unnecessary digits must be removed as long as when it does not affect the converted double value. For example, For double x = 0.010, x converted to string must be .01. For double x = 1.0, x converted to string must be 1..
One simply implementation is this. But I'd expect something more efficient rather than trial and error.
#include <stdio.h>
#include <stdlib.h>
char *d2s(double x) {
char format[100];
static char buf[100];
double y;
int i = 0;
while(1) {
sprintf(format, "%%.%dg", i++);
sprintf(buf, format, x);
y = atof(buf);
if(x == y) {
return buf;
}
}
}
int main() {
double x = 11111.1111111;
printf("%s\n", d2s(x)); // print "11111.1111111" as wanted.
return 0;
}
Note that there are bugs in the above code. For example, 1. is printed as 1. Something better is needed.
You may check out the function dtoa_r in http://www.netlib.org/fp/dtoa.c. Be warned, the code is massively complex. If I were to roll out my own convertor, I'd use your example function. To ensure 1. is output with decimal point, insert # in the specifier (so it becomes %%#.%dg).
to recover the original number
C language is a language without reflection - it can't inspect it's own source code. What was in the source code is not visible in the executable - as in, you can't recover the source code of a program by inspecting the executable.
In the case of a floating-point constants, the value is converted to the internal representation when compiling the program (C11 6.4.4.2p5), so the value of a floating-point constant is rounded to the nearest representable value, smaller or larger, then the actual value (C11 J.3.6 How the nearest representable...). Most probably in your code on your platform 1.00000001 can't be represented exactly as double, so the value 1.00000001 never exists in the resulting executable and it's not possible to recover it from the executable in any way.
The only way to recover 1.00000001 is to inspect the source code of your own program - you can write your own build system for that and write your own parser for that. The other way you could use is to use processor # operator to stringify the argument and specify the constant twice:
#define STRING(x) #x
printf("%s is converted to %a\n", STRING(1.00000001), 1.00000001);

Reading boolean with fscanf

Today I encountered a problem with scanf functions. Assume that you have a structure like the following example.
struct structA{
bool bVal;
int nVal;
}
If you run the following code
structA a;
a.nVal = 7;
...// Assume that we read a text file and the only text is "0"
fscanf(fp,"%d",&a.bVal);
printf("\n a.bVal=%d",a.bVal);
printf("\n a.nVal=%d",a.nVal);
It will print
a.bVal = 0
a.nVal = 0
The reason is that the fscanf function assumes a.bVal is an integer and overwrites the a.nVal first 3 bytes. This problem can be solved by the following dirty solution.
structA a;
a.nVal = 7;
...// Assume that we read a text file and the only text is "0"
int nBVAL;
fscanf(fp,"%d",&nBVAL);
a.bVal = nBVAL;
printf("\n a.bVal=%d",a.bVal);
printf("\n a.nVal=%d",a.nVal);
My question is that is there a cleaner and straightforward way of avoiding this problem beside the solution explained?
The solution you're proposing is the only portable one.
There is no conversion specifier for _Bool. There's also no guarantee about the storage size of a _Bool, except that it has at least CHAR_BIT bits. Even if you knew the size and tried something like %hhd, entering anything other than 1 or 0 would create a value that's invalid for a _Bool (scanf() would access the object through a char pointer, possibly writing the padding bits of the _Bool).
The only safe thing to do is to take input of a type you can handle and convert this to a _Bool where needed, as you're doing in your example.
Note there's no similar problem with printf(). A _Bool passed to printf() is promoted to int, so %d is fine.

C recursion does not recurse

My search did not yield any results. Also, my english is pretty bad, sorry for that.
So my program should do this:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
float rec();
int main()
{
setlocale(LC_ALL,"");
int w;
scanf("%d",&w);
printf("%f",rec(w));
return 0;
}
float rec(n)
{
if (n<1)
{
printf("Error");
}
else if (n==1)
{
return 6;
}
else if (n>1)
{
return 1/2*rec(n-1)+4;
}
return 0;
}
When the input is 1 it outputs 6, as it is supposed to.
When the input is <1 it outputs "Error0,000000".
When the input is >1 it only outputs the number that is added in
return 1/2*rec(n-1)+4;
In this case, it outputs 4. Why? Is rec(n-1) == 0?
My questions are:
Why won't it work?
How do i make it output "Error" instead of "Error0,000000" when the input is <1?
Integer division!
Here,
return 1/2*rec(n-1)+4;
1/2 will yields 0 due to integer division. So it's always going to be 4 as the final result.
Instead you can do:
return 1.0/2*rec(n-1)+4;
which will make sure the computation happens as double.
You might also simply want to add return 0; in the if (n<1) case and change the function definitio to:
float rec(int n) {... }
If you don't specify a type for n, it defaults to int in pre-C99. But this is no longer the case in C99 and C11.
The problem is mainly a type issue: try
return 1.0/2.0*rec(n-1)+4
to tell the compiler, that you want floating point arithmetic during the calculation. Otherwise, an integer division is performed and casted to float afterwards.
Fwiw: You wouldn't use a recursion for this, an iteration would fully suffice, be better understandable, perform better and needed less resources than the recursive version in c.
I would like to give you the answer of the second question.
You need a buffer for the return value of rec.
So,
float answer = rec(w);
if (NOTHING_HAPPENED)
print("%f", answer);
This will work!
In the case where n<1, you printf "Error" from the called routine, and then return 0 to be printf'd (as a float) in main. Don't do that ;-)
Personally, I'd check for the original being <1 in main as an alternative to calling rec() and printf.
This would be easier to answer if you'd tell us what it's supposed to produce.
However, I suspect your problem is related to rec() taking an integer argument, but returning a float. If you want recursive functions to behave sanely, their argument and return type should match. Quite likely your issue is that at some point you pass a decimal fraction that is approximately equal to 1, which does not get converted to 1 by the implicit type conversion.

Beginner type conversion

I am extremely new to programming in general, so please forgive my noobishness. I am trying to scale down the res[?] array in the function below. I know the problem that the res[?]*(multiplier/100) is creating a decimal answer instead of the required format which is an integer therefore I need to convert the result before it is plugged into the res[?].
I did think of turning res[] array into a double but I wasnt sure whether the initwindow(?,?) was compatible with integer values.
I am on mingw with code blocks. the linker and compiler has customized setting made by my professor. I am on Plain\basic C???
I tried to apply the techniques this website used about the truncating conversion. But doesn't seem to work. http://www.cs.tut.fi/~jkorpela/round.html
Debugger watcher shows that res[?] is equivalent to 0.
#include <stdio.h>
#include <graphics_lib.h>
#include <math.h>
int res[2]//contains a array which contains the vertical and horizontal detected resolution from main()
void function(res)
{
printf("Please note the lowest resolution available is 800x600\n");
printf("Please enter percentage ratio % below 100:");
scanf("%d",&multiplier);
res[1]=(int)(res[1]*(multiplier/100));
res[2]=(int)(res[2]*(multiplier/100));
blah blah blah blah.............
initwindow(res[1],res[2]) //from custom header that my professor made which initializes basic graphics window
return;
}
I'm assuming multiplier is an int to match the %d format.
multiplier/100 is guaranteed to be zero (if the user follows directions and provides a number less than 100). You can do (res[x]*multiplier)/100 to make sure the multiply happens first (you're probably okay without the parentheses, but rather than think about order of operations why not be explicit?)
The cast to int is unnecessary, because an int divided by another int is always an int.
Unless your professor has done some very interesting things, you should also note that a two-element array such as res would have elements res[0] and res[1], not res[1] and res[2].
you don't need to cast in this situation because the conversion is done implicitly . you only need a cast to assign the content of a variable to a variable of different type .
Looks like the multiplier variable is an int, so the result of multiplier/100 expression will be 0 in all cases.
Also, it's a good programming practice to check the validity of user's input.
You must declare multiplier before you use it:
int multiplier;
printf("Please note the lowest resolution available is 800x600\n");
printf("Please enter percentage ratio % below 100:");
scanf("%d",&multiplier);
And the index is staring from 0 not 1. And you should initialize res[0] and res[1] before using them. So:
res[0] = 800;
res[1] = 600;
And the division of multiplier by 100 will truncate to 0, try this without casting as it will be automaticly converted:
res[1]=(multiplier*res[0])/100;
res[1]=(multiplier*res[1])/100;

how to put an array character into the equation?

i try to put 8 byte character into the equation causing a lot of error,what i'm supposed to do to make sure the equation can take the static value and produce output in the 8 bytes.
#include <math.h>
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
void voltage_measure(void);
void main(void) {
voltage_measure();
}
void voltage_measure(void) {
char Van1[8],VA;
char Vbn[8],VB;
char Vcn[8],VC;
char AC[4],ac;
char BC[4],bc;
char AB[4],ab;
double Vab1,Vab2,Vbc1,Vbc2,Vac1,Vac2;
double Vab[8],Vbc[8],Vac[8];
Van1[0]=0xF0;
Van1[1]=0x00;
Van1[2]=0x00;
Van1[3]=0x00;
VA=0x000000F0;
Vbn[0]=0x78;
Vbn[1]=0x00;
Vbn[2]=0x00;
Vbn[3]=0x00;
VB=0x78;
Vcn[0]=0x3C;
Vcn[1]=0x00;
Vcn[2]=0x00;
Vcn[3]=0x00;
VC=0x3C;
AB[0]=0xB4;
AB[1]=0x00;
ab=0xB4;
AC[0]=0x2D;
AC[1]=0x00;
ac=0x2D;
BC[0]=0x5A;
BC[1]=0x00;
bc=0x5A;
Vab1=(VB*sin(ab))*(VB*sin(ab)) ;
Vab2=(VA+(VB*cos(ab)))*(VA+(VB*cos(ab)));
Vab[4]=sqrt(Vab1+Vab2);
Vbc1=(VC*sin(bc))*(VC*sin(bc));
Vbc2=(VB+(VC*cos(bc)))*(VB+(VC*cos(bc))) ;
Vbc[4]=sqrt(Vbc1+Vbc2);
Vac1=(VC*sin(ac))*(VC*sin(ac));
Vac2=(VA+(VC*cos(ac)))*(VA+(VC*cos(ac)));
Vac[4]=sqrt(Vac1+Vac2);
}
This is what I have understood as yet,
you want to do arithmetic with double precision that has several parameters
you would like to store the parameters in char variables (maybe to save on space?)
I don't know why you try to write VA=0x000000F0; when its a char (1 byte) variable
the static value you refer are probably the constants VA etc
It might be useful to have all these working in the arithmetic at double precision
when you use the sin and sqrt kind of functions, they will work at double anyways
you do not have a main function listed here;
it would be there in your actual file (that compiles this code)
so, i am also assuming you have things like math.h included
and the math library on the compile command
that is, you do get the binary compiled without errors
maybe you can elaborate the problem you are facing a little more?
Update from comment 1.
When you say, "character with 8 byte array" -- are you trying to create a double with an 8 char array?
Update from comment 2.
If your answer is in double, you can catch it in a double variable.
A double is already 8-bytes (on most platforms).
Is there a special reason to get it into a char array or a byte array?
Update from comment 3.
The link error implies you did include a math library for the linking.
The header just gives function prototypes for compilation.
With gcc, it would be -lm on the command line.
Update from comment 4.
To convert a double to an integer value check this page,
How can I convert a floating-point value to an integer in C?
Is the trouble that plain char on your machine is signed, so numbers such as 0xF0 are treated as -16 instead of +240? Did you know that on some machines, this is what will happen?
Concerning your link error you mentioned in the comments: including math.h is not enough, you have to tell the linker to add the library as well. Try adding "-lm" in your command line.

Resources