Getting Garbage value when converting Float to string? - c

I am getting garbage value when converting float to string. I cant use sprintf because it takes more memory and PIC24 microcontroller ram size is very low (128kb). When converting it gives some garbage values as ?39.88 like this What may be the problem . I am posting my code...
#include<stdio.h>
#include<string.h>
#include<math.h>
float Distance=0;
char str[15];
unsigned char *ftos(float f,int precision)
{
memset(str,0,sizeof(str));
float ff;
ff = f;
int a,b,c,k,l=0,m,i=0;
// check for negative float
if(f<0.0)
{
str[i++]='-';
f*=-1;
}
a=f; // extracting whole number
f-=a; // extracting decimal part
k = precision;
// number of digits in whole number
while(k>0)
{
l = pow(10.0f,k);
m = a/l;
if(m>0)
{
break;
}
k--;
}
// number of digits in whole number are k+1
/*
extracting most significant digit i.e. right most digit , and concatenating to string
obtained as quotient by dividing number by 10^k where k = (number of digit -1)
*/
for(l=k+1;l>0;l--)
{
b = pow(10.0f,l-1);
c = a/b;
str[i++]=c+48;
a%=b;
}
str[i++] = '.';
/* extracting decimal digits till precision */
for(l=0;l<precision;l++)
{
f*=10.0;
b = f;
str[i++]=b+48;
f-=b;
}
str[i]='\0';
return str;
}
void distance(float lat1, float lon1, float lat2, float lon2)
{
float dlon=0,dlat=0,a=0,c=0,dist=0;
dlon = (lon2 - lon1) * (M_PI / 180.0);
dlat = (lat2 - lat1) * (M_PI / 180.0);
a = pow(sin(dlat/2.0), 2) + cos(lat1*(M_PI / 180.0)) * cos(lat2*(M_PI / 180.0)) * pow(sin(dlon/2.0), 2);
c = 2 * atan2(sqrt(a), sqrt(1-a));
dist = 6367 * c;
Distance += dist;
}
int main()
{
distance(13.00659,80.121212,13.69898,80.256987);
printf("%s\n",ftos(Distance,6));
}
when i print the distance value after conversion it gives some garbage value... why?

Related

find square root with Newton using integers

In this program, I'm trying to calculate the square root with the newton equation 1/2(x+a/x) just using integers. So if I repeat this equation at least 10 times, it should divide the number by 1000 and give an approximate value of the square root of a/1000. This is the code:
int main (){
int32_t a, x; //integers a and x
float root;
do{
scanf ("%d", &a); // get value of a from the user
if (a < 1000 ){ // if chosen number is less than 1000 the programm ends.
break;
}
x = ((float) a / 1000); //starting value of x is a / 1000;
for (int i = 0; i < 50;i++)
{
root = ((float) x * (float) x + a/1000) / ((float)2*x); // convert int to float //through casting
x = (float)root; // refresh the value of x to be the root of the last value.
}
printf ("%f\n", (float)root);
}while (1);
return 0;
}
so if I calculate the square root of 2000, it should give back the square root of 2(1.414..), but it just gives an approximate value: 1.50000
How can I correct this using integers and casting them with float?
thanks
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char * *argv, char * *envp) {
int32_t a, x; //integers a and x
float root;
do {
scanf ("%d", &a); // get value of a from the user
if (a < 1000) { // if chosen number is less than 1000 the program ends.
break;
}
x = (int32_t)((float) a / 1000.0f); //starting value of x is a / 1000;
for (int i = 0; i < 1000; i++) {
// Fixed formula based on (x+a/x)/2
root = ((float)x + (((float)a) / (float)x)) / 2.0f;
//Below, wrong old formula
//root = ((float) x * (float) x + a / 1000) / ((float) 2 * x); // convert int to float //through casting
x = (int32_t) root; // refresh the value of x to be the root of the last value.
}
printf ("%f\n", root);
} while (1);
return (EXIT_SUCCESS);
}
The iterates of x = (x + a / x) / 2 for a = 2000000 and x0 = 1000 (all integer variables) are 1500, 1416 and 1414. Then 200000000 gives 14142 and so on.

How to create a float given an integer and the place of the decimal?

How can you generate a floating point given an integer and the decimal position?
For example:
int decimal = 1000;
int decimal_position = 3;
float value = 1.000;
I have accomplished this by using powers but that is not efficient
decimal/pow(10, decimal_position)
You can do this with a few integer multiplications and one floating point division:
int decimal = 1000;
int decimal_position = 3;
int offset = 1, i;
for (i=0; i<decimal_position; i++) {
offset *= 10;
}
float value = (float)decimal / offset;
Note that this works assuming decimal_position is non-negative and that 10decimal_position fits in an int.
How can you generate a floating point given an integer and the decimal position?
I have accomplished this by using powers but that is not efficient
float value = decimal/pow(10, decimal_position);
It depends on the range of decimal_position.
With 0 <= decimal_position < 8, code could use a table look-up.
const float tens[8] = { 1.0f, 0.1f, ..., 1.0e-7f };
float value = decimal*tens[decimal_position];
Yet to handle all int decimal and int decimal_position that result in a finite value, using float powf(float ), rather than double pow(double), should be the first choice.
// float power function
float value = decimal/powf(10.0f, decimal_position);
If not the best value is needed, code could *. This is slightly less precise as 0.1f is not exactly math 0.1. Yet * is usually faster than /.
float value = decimal*powf(0.1f, decimal_position);
Looping to avoid powf() could be done for small values of decimal_position
if (decimal_position < 0) {
if (decimal_position > -N) {
float ten = 1.0f;
while (++decimal_position < 0) ten *= 10.0f;
value = decimal*ten;
while (++decimal_position < 0) value /= 10.0f; // or value *= 0.1f;
} else {
value = decimal*powf(10.0f, -decimal_position);
}
} else {
if (decimal_position < N) {
float ten = 1.0f;
while (decimal_position-- > 0) ten *= 10.0f;
value = decimal/ten;
} else {
value = decimal/powf(10.0f, decimal_position); // alternate: *powf(0.1f, ...
}
}
Select processors may benefit with using pow() vs. powf(), yet I find powf() more commonly faster.
Of course if int decimal and int decimal_position are such that an integer answer is possible:
// example, assume 32-bit `int`
if (decimal_position <= 0 && decimal_position >= -9) {
const long long[10] = {1,10,100,1000,..., 1000000000};
value = decimal*i_ten[-decimal_position];
} else {
value = use above code ...
Or if abs(decimal_position) <= 19 and FP math expensive, consider:
unsigned long long ipow10(unsigned expo) {
unsigned long long ten = 10;
unsigned long long y = 1;
while (expo > 0) {
if (expo % 2u) {
y = ten * y;
}
expo /= 2u;
x *= ten;
}
return y;
}
if (decimal_position <= 0) {
value = 1.0f*decimal*ipow10(-decimal_position);
} else {
value = 1.0f*decimal/ipow10(decimal_position);
}
Or if abs(decimal_position) <= 27 ...
if (decimal_position <= 0) {
value = scalbnf(decimal, -decimal_position) * ipow5(-decimal_position);
} else {
value = scalbnf(decimal, -decimal_position) / ipow5(decimal_position);
}

Is it possible to replace a double number and write the program using only integers in C, with the same output?

Is it possible to write a program like this, using only the integer type and the standard library <stdio.h> in C? The output of the remainder must be displayed as a decimal number with two numbers behind the comma.
#include <stdio.h>
int num1 = 0;
int num2 = 1;
int num3 = 6;
int num4 = 3;
int num5 = 7;
int num6 = 3;
int num7 = 9;
int num8 = 8;
int sum, product, Result;
double division;
int main()
{
sum = num1 + num2 + num3 + num4;
product = num5 * num6 * num7;
Result = ((++product) - (sum++)) * sum;
int Integer_division = Result / (num8+ 1);
int Remainder = Result % (num8+ 1);
double division = Result / (num8+ 1);
printf("Result = %d\n", Result);
printf("Integer division = %d\n", Integer_division);
printf("Remainder = %d\n", Remainder);
printf("Division = %.02f\n", division);
return 0;
}
I was thinking about splitting it into two halves and printing it with a comma in between(%d.%d)
but that sounds like my last resort...
Thanks in advance.
To print floating-point like text from integers requires the sign, while-number part and the fraction part
char *sign = Result<0 ? "-":"";
int whole = abs(Integer_division);
char decimal_point = ','; // behind the comma.
int hundredths = abs(Remainder *100/(num8+ 1)); // Convert fraction to
1/100ths
// now print it
printf("%s%d%c%02d", sign, whole, decimal_point, hundredths);
Yet this displays only a truncated result. To round is work.
The usual way to mimic floating point output using integers it to consider the value as a fraction of 2 integer parts: numerator, denominator that needs scaling (e.g. x100 for .00 display) . For simplicity, assume denominator > 0.
First step is rounding due to finite display precision. Since the next step will involve an integer divide "truncate toward zero" and floating-point like display is usually "round to nearest", code needs to add a signed, unscaled 0.5 or one-half the denominator.
For simplicity, assume denominator > 0 and is odd so we can avoid half-way cases (even more work). Also assume no int overflow to avoid more work.
int numerator = Result;
int denominator = num8+ 1;
int scale = 100; // to print to 0.xx
int scaled_numerator = numerator * scale;
int scaled_half = denominator / 2;
if (scaled_numerator < 0) scaled_half = -scaled_half;
int rounded_scaled_numerator = scaled_numerator + scaled_half;
Now divide
int scaled_value = rounded_scaled_numerator/denominator;
char *sign = scaled_value<0 ? "-":"";
scaled_value = abs(scaled_value);
int whole = scaled_value / scale;
char decimal_point = ',';
int hundredths = scaled_value % scale;
printf("%s%d%c%02d", sign, whole, decimal_point, hundredths);

Swap digits in a double in C [duplicate]

This question already has answers here:
Exchange 1000s digit with 10s digit (C)
(3 answers)
Closed 5 years ago.
What I want to do in C is swap two digits in a double.
For example, if the input is 54321.987 and I want to swap the 2nd with the 4th digit, the output should be 52341.987.
Example when too small: 12.34 would output 1002.34.
Using stringification approach:
There are more elegant ways, but you can see the steps (and improve on) this pseudo code to stringify, move values, and convert back to number.
char buf1[20];
char buf2[20];
char *dummy;
double val = 54321.987;
sprintf(buf1, "%9.3f", val );
//Now the number is in string form: "54321.987". Just move the two elements
buf2[0]=buf1[0];
buf2[1]=buf1[3];
buf2[2]=buf1[2];
buf2[3]=buf1[1]; //and so on
//now convert back:
val = strtod(buf2, &dummy);
printf("%9.3f\n", val);
Or, a function could be used to do essentially the same thing: (still stringification)
double swap_num_char(double num, int precision, int c1, int c2); //zero index for c1 and c2
int main(void)
{
double val = 54321.987;
printf("%9.3f\n", swap_num_char(val, 3, 1, 3));
return 0;
}
double swap_num_char(double num, int precision, int c1, int c2)
{
char buf[25];
char format[10];
char *dummy;
char c;
sprintf(format, "%s0.%df", "%", precision);
sprintf(buf, format, num);
c = buf[c1];
buf[c1] = buf[c2];
buf[c2] = c;
num = strtod(buf, &dummy);
return num;
}
You can get the two digits you're interested in with simple operations:
You can do so with
double x = 54321.987;
double tens = ((int)(x / 10)) % 10; // Result is 2
double thousands = ((int)(x / 1000)) % 10; // Result is 4
Then you can subtract out the digits from their original place,
and add them back in a new place:
x = x - (tens * 10.0) - (thousands * 1000.0); // result is 50301.987
x = x + (tens * 1000.0) + (thousands * 10.0); // result is 52341.987
Now just reduce the expression:
x = x + tens * (1000.0 - 10.0) - thousands * (1000.0 - 10.0);
This leaves you with a final expression:
x += (tens - thousands) * 990.0;
Or, if you don't want the intermediate variables:
x += (((int)(x/10))%10 - ((int)(x/1000))%10) * 990;
One solution would be to extract the digits, then swap them.
You extract the digits (from positive numbers, at least) by using floor():
int place1 = 1; /* 0-based*/
double desiredPowerOf10 = powersOf10[place1];
double nextPowerOf10 = powersOf10[place1 + 1];
double digit1 = floor(number / desiredPowerOf10) - floor(number/nextPowerOf10) * 10;
You can then subtract the digits and add them back with the different powers:
double digitsRemoved = number - (digit1 * power1 + digit2 * power2);
double digitsSwapped = digitsRemoved + digit1 * power2 + digit2 * power1;
This may be susceptible to loss of precision with very large numbers, though.
1 - Use modf() to break the number into whole and fractional parts.
double modf(double value, double *iptr);
The modf functions break the argument value into integral and fractional parts, C11 ยง7.12.6.12
2 - Print the whole number part as a string and do the swap.
3 - Reconstruct
#include <float.h>
#include <math.h>
#include <stdio.h>
double swap2_4digit(double x) {
if (signbit(x)) {
return -swap2_4digit(-x);
}
printf("Before %f\n", x);
double ipart;
double fpart = modf(x, &ipart);
// ms_digit digits '.' '\0' min_size
char buf[1 + DBL_MAX_10_EXP + 1 + 1 + 4]; // Insure buffer is big enough
strcpy(buf, "0000"); // Handle small numbers
sprintf(buf + strlen(buf), "%.0f", ipart);
size_t len = strlen(buf);
char ch = buf[len - 2];
buf[len - 2] = buf[len - 4];
buf[len - 4] = ch;
x = atof(buf) + fpart;
printf("After %f\n", x);
return x;
}
int main(void) {
swap2_4digit(54321.987);
swap2_4digit(12.34);
}
Output
Before 54321.987000
After 52341.987000
Before 12.340000
After 1002.340000
Something left for OP. Make general for other digit positions.
If you want input number to be double then you can do something like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double numbergiven = 56789.1234;
double dummy;
double _4th_digit = (10*modf(numbergiven/10000, &dummy)) - modf(numbergiven/1000, &dummy);
double _2th_digit = (10*modf(numbergiven/100, &dummy)) - modf(numbergiven/10, &dummy);
numbergiven = numbergiven - (_4th_digit * 1000) + (_2th_digit * 1000);
numbergiven = numbergiven + (_4th_digit * 10) - (_2th_digit * 10);
printf("%lf",numbergiven);
return 0;
}
If you are not familiar with modf then you can simply do it this way:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double numbergiven = 56789.1234;
int number = numbergiven;
int _4th_digit = (number/1000) - (10*(number/10000));
int _2th_digit = (number/10) - (10*(number/100));
numbergiven = numbergiven - (_4th_digit * 1000) + (_2th_digit * 1000);
numbergiven = numbergiven + (_4th_digit * 10) - (_2th_digit * 10);
printf("%lf",numbergiven);
return 0;
}
or use fmod() #John Bollinger.
The fmod functions compute the floating-point remainder of x/y.
Extract the 2 digits each with the difference of modding with 10place and modding with 10place-1.
Subtract the 2 digits and then add them back swapped.
double swap_digit(double x, unsigned a, unsigned b) {
printf("Before %f\n", x);
double a_place = pow(10.0, a);
double b_place = pow(10.0, b);
double scaled_digit_a = fmod(x, a_place) - fmod(x, a_place/10);
double scaled_digit_b = fmod(x, b_place) - fmod(x, b_place/10);
x -= scaled_digit_a + scaled_digit_b;
x += scaled_digit_a/a_place*b_place + scaled_digit_b/b_place*a_place;
printf("After %f\n", x);
return x;
}
int main(void) {
swap_digit(54321.987,2,4);
swap_digit(12.34,2,4);
}
Output
Before 54321.987000
After 52341.987000
Before 12.340000
After 1002.340000
Double is stored in a memory as a sequence of bits, but you want to operate with decimal digits. Doing this with double variable you may not receive the original digits because of floating-point arithmetic.
Therefore, you should manipulate with string representation of double. The main aspect is how many digits string will contain. But it's obvious that you get number from input. Scan it as string, not as double.
There is a working code:
#include <stdio.h>
#include <stddef.h>
#define BUFSIZE 255
void swap_digits(char *str, int n, int m) {
char *digit1 = NULL;
char *digit2 = NULL;
int count = 0;
while (*str && (!digit1 || !digit2)) {
if (*str != '.') {
count++;
if (count == n) {
digit1 = str;
}
if (count == m) {
digit2 = str;
}
}
str++;
}
if (digit1 && digit2) {
char tmp = *digit1;
*digit1 = *digit2;
*digit2 = tmp;
}
}
int main(void) {
char buffer[BUFSIZE];
scanf("%s", buffer);
// it is preferably to validate input
swap_digits(buffer, 2, 4);
printf(buffer);
return 0;
}

Manually implementing a rounding function in C

I have written a C program (which is part of my project) to round off a float value to the given precision specified by the user. The function is something like this
float round_offf (float num, int precision)
What I have done in this program is convert the float number into a string and then processed it.
But is there a way to keep the number as float itself and implement the same.
Eg. num = 4.445 prec = 1 result = 4.4
Of course there is. Very simple:
#include <math.h>
float custom_round(float num, int prec)
{
int trunc = round(num * pow(10, prec));
return (float)trunc / pow(10, prec);
}
Edit: it seems to me that you want this because you think you can't have dynamic precision in a format string. Apparently, you can:
int precision = 3;
double pie = 3.14159265358979323648; // I'm hungry, I need a double pie
printf("Pi equals %.*lf\n", precision, pie);
This prints 3.142.
Yes:
float round_offf(float num, int precision)
{
int result;
int power;
power = pow(10, precision + 1);
result = num * power;
if ((result % 10) > 5)
result += 10;
result /= 10;
return ((float)result / (float)power);
}

Resources