I'm trying to scan a csv file.
Here is the code.
FILE *fp;
float pts[1000][2];
char line[1000];
int n = 0;
fp = fopen("abc.csv","r");
n = 0;
while(fgets(line, sizeof line, fp))
{
sscanf(line,"%f,%f",&pts[n][0],&pts[n][1]);
n++;
}
for(i=0;i<n;i++)
printf("%f, %f\n",pts[i][0],pts[i][1]);
suppose abc.csv contains
11.654,22.332
11.654,22.332
11.654,22.332
When I print, I get output as,
11.654000, 22.332001
11.654000, 22.332001
11.654000, 22.332001
where is the extra .000001 is coming from?
Any help is appreciated. Thanks in advance.
Nothing to do with the scanf. It is because of the way the float is represented/stored in memory.
Try the following:
float x = 22.332;
printf("%f\n", x);
You will see the result is the same.
Look at: https://softwareengineering.stackexchange.com/questions/101163/what-causes-floating-point-rounding-errors
Floating point numbers are stored in memory with standards like IEEE-754 (single or double), these standards could not represent every floating point number you expect because they're floating point. the accuracy of floating point storage isn't constant so they try to round up numbers to nearest possible number they can store.
Also the default precision of the %f in printf is 6, you can set it to 3
printf("%.3f, %.3f\n",pts[i][0],pts[i][1]);
Related
I'm storing the result of a calculation inside a long double variable that I need to print out. I need a way to discriminate between large numbers and small numbers. For example If I want to print tan(pi/4) it should be 1, the same for the result of a multiplication like '5*3' I want to be 15 without trailing zeros. On the other hand, I want to represent small numbers like the elementary charge 1.602176634e-19 using the scientific notation. This is what I tried
void print(long double number) {
long double i;
long double tmp = ceil(number);
if (fabs(number-tmp) < 0.00000001)
number = tmp;
long double r = modfl(number, &i);
if (fabs(r) <.0000000000000001 && fabs(r) <.00001)
printf("%.Lf ", i);
else if (fabs(r) <.00001)
printf("%.Lf ", i);
else printf("%.19Lf ", number);
}
If I try to print the mass of a proton 1.6726219236951e-27 with this code I get 0, the rest of the quantities I mentioned before are displayed correctly.
I am programming a uC in C language and I need to show a float number with 4 precision digits. The thing here is that my number is not really a float type. I have the integer part and the decimal part of the number in two different integer variables. Let say: int digit and int decimal.
I tried using printf ("%d.%d"); That works fine when my decimal number is 6524, but the problem comes when it is exactly 65 since it doesnt show 4 decimals.
I tried using printf ("%d.%04d"); but when my decimal part is exactly 65 it shows 0065 which is not mathematically correct (I would need 6500)
I looked for any argument of printf which completes with zeros at the end but could not find anything. All of them complete with leading zeros which is not useful for me in this case.
I also though about checking if my number is minor that 10, 100 or 1000 and multiply it by 1000, 100 or 10 respectively. But it will not work when the decimal part is exactly 0, since 0*1000 will still be 0 and not 0000.
Any idea on how to solve this? Please let me know if I am not completely clear and I will provide more information
Thanks!
Since printf returns the number of characters printed, you can do it, somewhat clumsily, as follows:
printf("%d.", int_part);
int digits = printf("%d", frac_part);
while (digits++ < 4) putchar('0');
I have to say, though, that it is a very eccentric form of representing a floating point number, and you might seriously want to rethink it.
Another wired possibility is to convert the decimal part to a string and then fill it with 0:
int main() {
int i, d, len;
char p[10];
i = 189;
d = 51;
// convert the number to string and count the digits
snprintf(p, 10, "%d", d);
len = strlen(p);
while (len < 4) {p[len] = '0'; len++;}
p[len] = '\0';
fprintf(stdout, "%d.%s\n", i, p);
// you can also go back to int
d = atoi(p);
fprintf(stdout, "%d.%d\n", i, d);
}
Combine both your answers: multiply by 10, 100 or 1000 as necessary, but still print with %04d.
Right, i have a 2 files (Distance and time) that have different values on their rows, in the program that divides both values on line into their speed and displays on screen.
This works perfectly, however, the function gives the calculated value to the nearest whole number:
#include <stdio.h>
int main()
{
FILE *fTotDc;
FILE *fTotTc;
int CalScD; //Values for total cycling speed
int CalScT;
float CalScS;
char ScSValue[32];
int DataCount=1; //File line comparison
struct store06 //TICtotD
{
char defTotDc[16];
}stock06[512];
struct store08 //TICtotT
{
char defTotTc[16];
}stock08[512];
fTotDc=fopen("TICtotD.txt","r"); //Opens total distance
fscanf(fTotDc,"%16[^\n]%*.2f", stock06[DataCount].defTotDc);
fTotTc=fopen("TICtotT.txt","r"); //Opens total time
fscanf(fTotTc,"%16[^\n]%*.2f", stock08[DataCount].defTotTc);
printf("|Distance |Time |Speed |");
printf("\n");
printf("|%-16s", stock06[DataCount].defTotDc);
printf("|%-16s", stock08[DataCount].defTotTc);
CalScD = atoi(stock06[DataCount].defTotDc); //Totals are converted to int for calculation
CalScT = atoi(stock08[DataCount].defTotTc);
if(CalScT == 0) //Test for 1/0 error, There is also a failsafe in the edit function which checks for t=0;
{
if(CalScD == 0) //If distance is 0 (As it is by default), the speed is 0.
{
printf("|0 ");
}
else //If distance is not 0 , we have (1/0)*k, which doesn't exist.
{
printf("|Error, Time is 0");//Error message given.
}
}
else
{
CalScS = CalScD/CalScT;
snprintf(ScSValue,32,"%.2f", CalScS); //Turns this int value into a string
printf("|%-16s",ScSValue); //String outputted
}
printf("|"); //last column
getch();
}
This is the code for one line, given that this on a do-while loop until the end of the file.
Input (distance file): Line 1: 4 , (time file) Line 1: 1 .
Expected speed output: 0.25
Actual output: 0.00
Edit: My coding skills are RIP
Edit 2: The mistake, assuming interger/interger would automatically calculate a floating point value. I have changed the code accordingly, it works. Thank you guys.
In CalScS = CalScD/CalScT; first the integer division is executed, then the resulting value is converted to float and assigned to the variable.
Try this
CalScS = CalScD/(double)CalScT;
To first convert the denominator to floating point, then do the division and assign correctly.
Oh ... and (almost) always prefer double to float.
Your calculation line CalScS = CalScD/CalScT; is doing integer division, since both operands are integers.
You need one (or both) of the operands to be floats (or doubles) to get floating-point division.
In your code
int CalScD; //Values for total cycling speed
int CalScT;
both are of type int, and CalScS is of type float.
While calculating the division using
CalScS = CalScD/CalScT;
first, the division will be performed as integer division [resulting in an int value] and after that, the int result will be promoted to float. That's why you're getting the integer output.
change
CalScS = CalScD/CalScT;
to
CalScS = ((float)CalScD )/CalScT;
to enforce the floating point division.
Suppose the file is organized in this way:
1.2 # 3.4 # 4.0
2.3 # 2.3 # 1.2
Read the file in C and store data in an array. Meanwhile, you should judge how many lines there are.
My problem is 1) I don't know how to declare the array as I don't know how many numbers exist in the file, so should I go over the file previously and count the number?
2) I don't know how to judge line number as the last '\n' in the file may exist or may not.
The answer to 1) How to declare the array if you don't know the number of elements in advance, is unsolvable with primitive vectors, you'll have to create your own growing-capable vector.
typedef struct {
double * v;
unsigned int size;
} Vector;
This struct is the basis of the new data type. You'll need an API such as:
Vector createVector();
void addToVector(Vector *v, double x);
double getFromVector(Vector *v, unsigned int pos);
void modifyInVector(Vector *v, unsigned int pos, double x);
unsigned int sizeOfVector(Vector * v);
void destroyVector(Vector *v);
The key members of the API are createVector, destroyVector and addToVector. Since this is probably homework, I won't resolve this to you.
In createVector, you basically have to put all fields to 0.
In destroyVector, you have to free() v;
In addToVector, you'll have to resize() the reserved space so another new item fits:
size_t newSize = ( v->size +1 ) * sizeof( double );
Now you have to call realloc() with the new size.
And that's basically all. If you want better performance, you can introduce also the capacity of the vector, so you don't have to make it grow each time you add a new value. For example, the people that built the STL in C++ make the vector class grow to its double each time the capacity is exceeded. But, anyway, that's another story.
atof (ascii to float):
http://en.wikipedia.org/wiki/Atof
Use fscanf:
The fscanf() function shall read from the named input stream. [...] Each function reads bytes, interprets them according to a format, and stores the results in its arguments. Each expects, as arguments, a control string format described below, and a set of pointer arguments indicating where the converted input should be stored.
The following code reads from the stdin console, processes the numbers in the format you gave and prints them out again so one can check for correctness.
#include <stdio.h>
int main(int ac, char *av[])
{
float a, b, c;
scanf("%f # %f # %f", &a, &b, &c);
printf("%f # %f # %f", a, b, c);
printf("\n");
}
Albeit this code works, it is not very robust. It requires the EXACT sequence ' # ' of characters between numbers and there is nothing but a newline allowed after the last number in a row.
For a more robust solution you would have to find the character index of the start of each number and do a fscanf on that location.
Floating point has precision loss for decimal fractions. For example, a simple number like "0.1" needs an infinite number of bits to represent it accurately.
For the numbers you've shown (only one digit after the decimal point), a better idea would be to multiply each number by 10 to avoid the precision loss that floating point would cause. This would involve writing your own "ASCII to integer" conversion routine that pretends the decimal point is one place to the right of where it actually is. It would also save space, as (for the numbers you've shown, where no number is greater than 25.6) you could store them in an array of 8-bit integers (chars).
Good luck with your homework!
i'm reading tokens from file, it enters the char pointers perfectly as it comes
in the file, but after sending it to this function:
double CharToDouble(char *ptemp)
{
if(ptemp != NULL)
{
if(ptemp[0] == '0')
return atof(ptemp);
else
return atof(ptemp)/100;
}
return 0;
}
the values i'm getting in the doubles where i save this function result are like 0.6600000000001
0.280000000000000000
and stuff like that, i want it to be ecaxtly as in the char*..
it's money issues, in cents.
any idea?
If it's a currency, multiply by 100 and round down to an integer, so instead of 123.45, you have 12345.
Note: Float and Double are accurate only up to a certain precision (machine precision), because not every real number can be encoded in the floating point format.
When you're only interested in output of the correct format, you must use the correct printf command, i.e.
double currency_value = 9.95;
printf("Currency: %.2f", currency_value)
Look up "Format String" to learn more. The %.2f says that I want a floating point number with a fixed position after the comma (f) and that this position should be the second number after the comma (2).