I've read the questions regarding the implementation of rounding in C, inspired by MATLAB round function and I followed their advice but the result is not at all what it should be. Here's part of my code regarding this issue:
movmean_h[i]=(double)sum/(f-b);
mexPrintf("\t movmean_h[%d]=%e",i,movmean_h[i]);
movmean_h[i]=(double)round(movmean_h[i]*n)/n;
mexPrintf("\t movmean_h[%d]=%e",i,movmean_h[i]);
And part of the result is like this(this code is run in a loop):
movmean_h[10261]=2.283693e-13 movmean_h[10261]=1.668138e-06
movmean_h[10261]=2.283693e-13 movmean_h[10261]=1.668138e-06
movmean_h[10262]=2.288172e-13 movmean_h[10262]=1.483963e-06
movmean_h[10263]=2.292687e-13 movmean_h[10263]=-8.838173e-07
movmean_h[10264]=2.297219e-13 movmean_h[10264]=0.000000e+00
movmean_h[10265]=2.292835e-13 movmean_h[10265]=2.138378e-06
movmean_h[10266]=2.288319e-13 movmean_h[10266]=1.409754e-06
movmean_h[10267]=2.283839e-13 movmean_h[10267]=0.000000e+00
movmean_h[10268]=2.279412e-13 movmean_h[10268]=-2.147484e-06
movmean_h[10269]=2.275056e-13 movmean_h[10269]=-2.147484e-06
movmean_h[10270]=2.270787e-13 movmean_h[10270]=-2.147484e-06
movmean_h[10262]=2.288172e-13 movmean_h[10262]=1.483963e-06
movmean_h[10263]=2.292687e-13 movmean_h[10263]=-8.838173e-07
movmean_h[10264]=2.297219e-13 movmean_h[10264]=0.000000e+00
movmean_h[10265]=2.292835e-13 movmean_h[10265]=2.138378e-06
movmean_h[10266]=2.288319e-13 movmean_h[10266]=1.409754e-06
movmean_h[10267]=2.283839e-13 movmean_h[10267]=0.000000e+00
movmean_h[10268]=2.279412e-13 movmean_h[10268]=-2.147484e-06
movmean_h[10269]=2.275056e-13 movmean_h[10269]=-2.147484e-06
movmean_h[10270]=2.270787e-13 movmean_h[10270]=-2.147484e-06
The answers do not match at all, not in order and not in the decimals, which in theory they would match.
And 'n' is defined as:
long int n=pow(10,15);
So my question is why my code is wrong, or is there something I'm missing?
By the way I am writing my C code for a MATLAB mex-file.
Code lacked a declaration of declaration of double round(). Older compilers allow this, yet interpret the result then an int. Code output is then quite bizarre. The hint, for me, was that many nearby double inputs had the same result.
// add
#include <math.h>
10^15 doesn't fit into a long int on a Windows machine. Use a double.
double n = pow(10, 15);
movmean_h[i]=(double)sum/(f-b);
mexPrintf("\t movmean_h[%d]=%e",i,movmean_h[i]);
movmean_h[i]=round(movmean_h[i]*n)/n;
mexPrintf("\t movmean_h[%d]=%e",i,movmean_h[i]);
Related
I write c embedded on STM32F437VI. At some point, I need to parse some strings that contain numbers, as float numbers. I use atof and it works always with the correct result, except for this one weird case. If the string is 0 or 0.0 it gives 2.
I have included stdlib.h and even tried (float)atof() to typecast, but for some weird reason, the float variable has always the value 2 from the atof("0") operation and the double value has the correct 0.
Why is this happening? Thank you all in advance.
#include "stdio.h"
#include "stdlib.h"
int main(void)
{
char test[] = "0";
float val1;
double val2;
val1 = atof(test);
val2 = atof(test);
return 0;
}
I expect the obvious result of 0 to the float variable as well, but it keeps getting the fixed 2 value.
UPDATE:
This code section is part of a much bigger project and there is no point in elaborating on the project. I have custom Makefile with LDFLAG option
"-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float".
Could this affect this issue?
As the MCV example is concerned, in main.c I have the above code section and I got the results mentioned.
Can anybody think of any reason atof() behaves in this way?
Of course I have used online c compiler as well with the exact same code and the result is of course 0. I guess if something was very very wrong with the stdlib library, then atof() would not work for all the other cases as well. But it fails only for "0" and only with the result 2 assigned to the float variable.
I watch the variables realtime with Ozone debugger software.
Could the reason be the floating point implementation on STM32F4 mcu used? A missing parameter in the custom Makefile or something like that?
First, your question lacks a Minimal, Complete, and Verifiable example.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char test[] = "0";
float val1;
double val2;
val1 = atof(test);
printf("%f\n", val1);
val2 = atof(test);
printf("%f\n", val2);
}
Output:
0.000000
0.000000
<°)))<()
Or your standard library implementation is fubar.
It looks like the cause of your problem is in the updated question text:
UPDATE: This code section is part of a much bigger project and there is no point in elaborating on the project. I have custom Makefile with LDFLAG option
"-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float".
Assuming these options are changes vs the defaults, what you're doing is telling the compiler to generate code for a different ABI from your toolchain's library ecosystem. The code generated for main expects the result of atof in a floating point register, but atof is using the standard ABI, which passes floating point arguments and return values in general-purpose registers. Thus, main is just reading whatever junk happens to be left in the floating point registers used for return values.
See if your problem goes away if you remove -mfloat-abi=hard. If so, you've probably found your problem. You need to either build a toolchain and libraries for the hardfloat ABI, or stick with the default non-hardfloat calling convention.
I am trying to learn c from a book but I am confused
I did the following:
#include <stdio.h>
#include <math.h>
int main(void)
{
int metrisi=getchar();
putchar (metrisi);
float proi=(metrisi-80)/40*1.5;
float apog=(metrisi-80)/40*1.4;
float brady=(metrisi-80)/40*1.4;
{
printf("%5.0f %5.0f %5.0f\n", proi,apog,brady);
}
return 0;
}
The output is
C Online Compiler [gcc-6.3]
Copyright (c) Free Software Foundation, Inc.
Compiling your program...
Build completed successfully!
Running your program...
\xff...
The program executed successfully!
Could you please help me? No input from the user, no output.
Thank you
Several problems:
int metrisi=getchar();
This will place the ASCII value of the first letter you type into metrisi.
You can get the decimal value of that by substracting 48, but that is quite unsafe - what happens if you input anthing other than a digit?
EDIT: As David pointed out, that substraction is technically not unsafe. However, since you want to do some arithmetic on your input values, it would be wise to make sure you only accept numbers as input.
Anyhow, the next problem is in your printf:
printf("%5.0f %5.0f %5.0f\n", proi,apog,brady);
Here you specify to output 5 digits to the left of the decimal point, and 0 digits after the decimal point. Maybe you wanted this:
printf("%.5f %.5f %.5f\n", proi,apog,brady);
There also is (my guess) a problem here:
float proi=(metrisi-80)/40*1.5;
This expression might yield quite surprising results. The reason for that is that there is something called operator precedence in C, and it is not always intuitive.
You could try this instead:
float proi=(metrisi-80)/(float)40*1.5;
or
float proi=(metrisi-80)/40.0*1.5;
What is wrong with this code? I am learning both Python and C at the same time. Similar code on Python works fine but I am confused why this does not work here?
#include <stdio.h>
float a, b, c,min_value, max_value;
int main(){
printf("Enter a number here:");
scanf("%f",&a);
b=(max_value+min_value)/2;
while(abs(b*b-a)>0.1){
if (b*b>a){
max_value=b;
b=(max_value+min_value)/2;
}
else if(b*b<a){
min_value=a;
b=(max_value+min_value)/2;
}
printf("the square root of the number is %f",b);
}
}
In C, abs is an integer function - passing float values to it will result in truncation, so small values < +/-1.0 will just become 0. You need to use fabs for floating point values. Change:
while(abs(b*b-a)>0.1){
to:
while(fabs(b*b-a)>0.1){
and add:
#include <math.h>
near the top of your source file.
A lot of things are wrong:
float a, b, c,min_value, max_value;
You shouldn't declare these variables outside the main function.
b=(max_value+min_value)/2;
max_value and min_value are not defined, what are you expecting here?
if (b*b>a){
max_value=b;
b=(max_value+min_value)/2;
}
else if(b*b<a){
min_value=a;
b=(max_value+min_value)/2;
}
Once again, max_value and min_value may not be defined. I could continue.
If you are trying to implement a sqrt function, perhaps you should take a look at someone else's code, as it seems obvious you lack knowledge in C.
For future references, please state what your program is trying to accomplish and what errors are occuring. Not trying to be mean or condescending; just giving you a heads up on Stack Overflow policy on question phrasing.
That said, on a brief glance I did notice that you also did not define "max_value" or "min_value" before using them in line 6 (where you set a value to "b"). In addition, declaring your variables outside the main function makes them global variables, which I would suggest avoiding if your variables are not going to be used in another program (via "#include ").
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;
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.