How to convert a string to double floating-point value? - c

sorry if the title is confusing, I just need some experienced programmers to attempt to clarify something for me. So one of my homework questions asks me this (the language is c):
Write a function that receives a string and returns a double floating-point value. The fucntion declaration would look like this
double convertFloat(char s[]);
Do not use the strtol() function or any other standard c library function. Write your own!... Note that the input string could have any of the following sample formats: "1.34", "-1.4554", "6".
I am just not sure how to approach this because I am not sure what is being asked here. If I had to write a function to find a square root or something like that I could do it no problem but it seems that I have to take strings that are all numbers and convert them to floats... just not sure where to start and googling similar things has yielded no results.
Thank you all in advance.
- Davey

Start by writing
unsigned int convertUnsignedInt(const char *s);
// e.g. convertUnsignedInt("42") == 42
It's a bit simpler because you don't have to handle negative numbers or fractions, but it shows the general principle.

Here is the complete code to your problem. The code is understandable. Ask if you have any doubts regarding it.
#include <stdio.h>
int power(int n, int m)
{
if (m == 1)
return n;
else
return n * (power(n, m - 1));
}
int getLength(char s[])
{
int i = 0;
for(i = 0; s[i] != '\0'; i++);
return i;
}
double convertFloat(char s[])
{
int len = getLength(s);
int dotpos = 0;
double result = 0.0f;
int n = 0, flag = 0;
if(s[0] == '-')
{
n = 1;
flag = 1;
}
for (; n < len; n++)
{
if (s[n] == '.')
{
dotpos = len - n - 1;
}
else
{
result = result * 10 + (s[n] - '0');
}
}
result /= power(10, dotpos);
if(flag)
return result*-1;
return result;
}
int main()
{
char str[] = "126433.47";
printf("%f", convertFloat(str));
}

Related

Struggling with PairInverse problem in c using recursion [duplicate]

I encountered a hard question I don't know the answer to: "Rearrange the digits from an integer in blocks of two with a recursive function" here's an example:
Input: 123456
unsigned long pairinvPrint(unsigned long number) {
printf("%d", number % 100);
if ((number / 100) <= 99) {
printf("%d", number / 100);
}
else {
pairinv(number / 100);
}
}
Output: 563412
More I/O Examples: 42 -> 42; 1234 -> 3412
However, the set circumstances to do this are hard (no loops, arrays, pointers, global- or static variables, no libraries) and it should not print the solution directly, rather return it upon a call like this:
printf("Rearrange int (%lu) = %lu", input, pairinvert(input));
Luckily there's one circumstance to make it easier, the number of the input digits is always even.
Now I experimented for a while, but cant come up with a working solution, except the invalid one using printf.
Does anyone have some inspiration for me or idea how to tackle this?
I'll bite :-)
unsigned long p(unsigned long p1, unsigned long p2) {
// no loops, no arrays, no pointers, no global, no static, no variables, no libraries
if (p1 < 100) return p2*100 + p1;
return p(p1/100, p2*100 + p1%100);
}
unsigned long pairinvert(unsigned long n) {
// no loops, no arrays, no pointers, no global, no static, no variables, no libraries
if (n < 100) return n;
return p(n/100, n%100);
}
// need <stdio.h> for printf()
#include <stdio.h>
int main(void) {
unsigned long input;
input = 123456;
printf("Rearrange int (%lu) = %lu\n", input, pairinvert(input));
input = 42;
printf("Rearrange int (%lu) = %lu\n", input, pairinvert(input));
input = 1234;
printf("Rearrange int (%lu) = %lu\n", input, pairinvert(input));
}
Following program should work.
#include <stdio.h>
void rearrange(int n, int *output) {
int lsd = 0, slsd = 0;
if(n == 0)
return;
if(n > 0) {
lsd = n%10;
}
if (n > 9) {
slsd = (n%100)/10;
}
*output = 100*(*output) + 10*slsd + lsd;
n = n/100;
rearrange(n, output);
}
int main() {
int n;
int output = 0;
scanf("%d", &n);
rearrange(n, &output);
printf("%d\n", output);
return 0;
}
It is simple to understand, so I am not writing any comments.
Note that it is tail recursive so with O2 optimization it can recurse infinitely.
Try this :
unsigned long pairinv(unsigned long number, unsigned long result) {
unsigned long n = number % 100; // Gets the two digit number
if (n == 0) return result; // If it's zero returns the result
result = result * 100 + n; // Else multiplies the result by 100, adds n
return pairinv(number / 100, result); // and continues by recursion
}
int main() {
unsigned long r= 0;
printf("%lu\n", pairinv(123456, r)); //==> 563412
return 0;
}

Multiplying a large number in C with a single digit number recursively?

I'm having trouble creating a recursive program that multiplies a large number with a single digit number. I understand they're are simpler methods to doing this, but I would like to do it recursively. I provided a SSCCE in the code. The problem is that the multiplication is not occurring correctly. For numbers with more than 1 digit, the program will only multiply the last digit, instead of multiplying the entire number.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *getmem(int len) {
char *ret;
ret = malloc(len);
if (NULL == ret) {
printf("memory allocation failed!\n");
exit (0);
}
else
return ret;
}
void printdigs(char *digs) {
if('0' == digs[0]) {
if (0 == digs[1]){
printf("%s", digs);
return;
}
else printdigs(&digs[1]);
}
else printf("%s",digs);
}
void multi_helper(char *a, char *r, char b, int len, int carry) {
int sum;
if (-1 == len) {
r[0] = (char) (carry + 48);
return;
}
sum = (a[len]-48) * (b-48) +carry;
r[len+1] = (char) ((sum % 10) + 48);
if (sum > 9)
carry = 1;
else carry = 0;
multi_helper(a,r,'0', len-1,carry);
}
char *multi(char *a, char b) {
char *res;
int l = strlen(a);
res = getmem(l + 2);
res[l+1] = 0;
multi_helper(a, res, b, l-1,0);
return res;
}
int main(int argc, char *argv[]) {
char *n1 = "1000";
printf("%s multiplied by 5 is ", n1);
printdigs(multi(n1,"5"));
printf("\n");
return 0;
}
Thanks for any help.
printdigs(multi(n1,"5"));
to
printdigs(multi(n1,'5'));
also need free return value of function multi
multi_helper(a,r,'0', len-1,carry);
to
multi_helper(a,r,b, len-1,carry);
I don't really know what you're looking for (this doesn't use strings to store numbers), but this uses recursion to add a number to itself a certain number of times (multiplication) using recursion for counting how many iterations are left.
int recursive_multiply(a, b) {
if (b==0) {
return 0;
}
char sign = 1;
if (b < 0) {
sign = -1;
b = -b;
}
return (a + recursive_multiply(a, b-1)) * sign;
}
edit: with the updates to the question, it's clear this solution doesn't directly answer the question Ace has, but it may answer questions other people may have when they search for something similar to the question, so I'm going to leave it. If anyone thinks this is wrong, comment and I'll consider removing it if warranted.

Convert string to integer recursively?

Here is a simple function that converts a string to an integer.
int str2int(char *str)
{
int ret = 0;
char *c;
for (c = str; (*c != '\0') && isdigit(*c); ++c)
ret = ret*10 + *c - '0';
return ret;
}
As an exercise, I'd like to write a recursive function that does the same thing. This is what I came up with.
int str2int2(char *c, int *i)
{
if (*c == '\0' || !isdigit(*c))
return *i;
*i = *i * 10 + *c - '0';
return str2int2(c + 1, i);
}
.
.
int i = 0;
.
... str2int2(str, &i);
Is there a way to write the recursive function without using the extra int* argument?
Sure, it's easy enough, but you need to write two functions, one with an accumulator, like this:
int str2int_rec(char *c, int accum)
{
if (!c || !*c || !isdigit(*c))
return accum;
return str2int_rec(c + 1, accum * 10 + (*c - '0'));
}
int str2int(char *c)
{
return str2int_rec(c, 0);
}
Well, you could hide the functionality from the person using the function. So you will have a function named int str2int(char *str) which will call int str2int(char *c, int *i) thereafter.
It's how I've done it in the past.
I think you may use horner scheme in order not to keep any 'i'.
You must reverse the string (yeah quit ugly) and then you can simply use:
int str2int (char* str)
{
if (*str+1)
{
return 10*str2int(str+1)+(*str-'0');
}
return 0;
}
One way could involve passing the length of the digit as an argument so we can read backwards efficiently:
int strtoi(char *c, size_t l)
{
return l ? c[l-1] - '0' + 10 * strtoi(c, l - 1) : 0;
}
Then call it like this:
int i = strtoi("432", 3);
Or:
char *c = "432";
int i = strtoi(c, strlen(c));
But it's not always optimal to bother with the length of a string. Plus, if a string has characters after a number, we'd have to factor that in manually, because this function won't do it for us. We can't (shouldn't) use strlen() inside our function to avoid having to pass arguments, because that can cause a considerable slowdown to recalculate the string's length every time. Surely there must be a way to do this from the beginning, even if we have to bring out the heavy artillery:
int strtoi(char *c)
{
if(!isdigit(*c)) return 0;
int i = strtoi(c + 1);
return i + pow(10, (int)(log(i + 1)/log(10)) + (i != 0)) * (*c - '0');
}
And no, that (int) cast isn't optional. Basically, all of that math calculates the power of 10 we need to multiply our current digit by, based on the number returned by the last recursive call.
I understand this is probably a learning exercise, but recursion is not the be-all, end-all of programming. In some languages, and for some tasks, it is what some, myself included, would call beautiful, but from the looks of it this is not one of those cases.

Is there a strtol equivalent that does not require a null-terminated string?

Is there a standard C function similar to strtol which will take a char* and a length for a non-null-terminated string?
I know that I could copy out the string into a null-terminated region, but for efficiency reasons that is undesirable.
No such function in the standard library. You will either have to use the temporary buffer method, or write your own function from scratch.
To answer your question: no, there is no standard function, but it is simple enough to write your own:
#include <stdio.h>
#include <ctype.h>
int natoi(char *s, int n)
{
int x = 0;
while(isdigit(s[0]) && n--)
{
x = x * 10 + (s[0] - '0');
s++;
}
return x;
}
int main(int argc, char*argv[])
{
int i;
for(i = 1; i < argc; i++)
printf("%d: %d\n", i, natoi(argv[i], 5));
}
strntol is probably what you're after... it's not standard C, though.
If you're that pressed for efficiency, you can probably motivate the time to write and debug your own.
But: just do it with a copy; you probably have an upper bound for how long the string can be (a decimal numeral that fits in a long has a strict upper bound on its maximum length), so you can have a static buffer. Then profile your entire application, and see if the copying/conversion really is a bottleneck. If it really is, then you know you need to write your own.
Here's a rough (untested, browser-written) starting point:
long limited_strtol(const char *string, size_t len)
{
long sign = 1;
long value = 0;
for(; len > 0 && *string == '-'; string++, len--)
sign *= -1;
for(; len > 0 && isdigit(*string); string++, len--)
{
value *= 10;
value += *string - '0';
len--;
string++;
}
return sign * value;
}

Algorithm to convert infinitely long base 2^32 number to printable base 10

I'm representing an infinitely precise integer as an array of unsigned ints for processing on a GPU. For debugging purposes I'd like to print the base 10 representation of one of these numbers, but am having difficulty wrapping my head around it. Here's what I'd like to do:
//the number 4*(2^32)^2+5*(2^32)^1+6*(2^32)^0
unsigned int aNumber[3] = {4,5,6};
char base10TextRepresentation[50];
convertBase2To32ToBase10Text(aNumber,base10TextRepresentation);
Any suggestions on how to approach this problem?
Edit: Here's a complete implementation thanks to drhirsch
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#define SIZE 4
uint32_t divideBy10(uint32_t * number) {
uint32_t r = 0;
uint32_t d;
for (int i=0; i<SIZE; ++i) {
d = (number[i] + r*0x100000000) / 10;
r = (number[i] + r*0x100000000) % 10;
number[i] = d;
}
return r;
}
int zero(uint32_t* number) {
for (int i=0; i<SIZE; ++i) {
if (number[i] != 0) {
return 0;
}
}
return 1;
}
void swap(char *a, char *b) {
char tmp = *a;
*a = *b;
*b = tmp;
}
void reverse(char *str) {
int x = strlen(str);
for (int y = 0; y < x/2; y++) {
swap(&str[y],&str[x-y-1]);
}
}
void convertTo10Text(uint32_t* number, char* buf) {
int n = 0;
do {
int digit = divideBy10(number);
buf[n++] = digit + '0';
} while(!zero(number));
buf[n] = '\0';
reverse(buf);
}
int main(int argc, char** argv) {
uint32_t aNumber[SIZE] = {0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
uint32_t bNumber[4] = {1,0,0,0};
char base10TextRepresentation[50];
convertTo10Text(aNumber, base10TextRepresentation);
printf("%s\n",base10TextRepresentation);
convertTo10Text(bNumber, base10TextRepresentation);
printf("%s\n",base10TextRepresentation);
}
If you have access to 64 bit arithmetic, it is easier. I would do something along the line of:
int32_t divideBy10(int32_t* number) {
uint32_t r = 0;
uint32_t d;
for (int i=0; i<SIZE; ++i) {
d = (number[i] + r*0x100000000) / 10;
r = (number[i] + r*0x100000000) % 10;
number[i] = d;
number[i] = r;
}
void convertTo10Text(int32_t* number, char* buf) {
do {
digit = divideBy10(number);
*buf++ = digit + '0';
} while (!isEqual(number, zero));
reverse(buf);
}
isEqual() and reverse() left to be implemented. divideBy10 divides by 10 and returns the remainder.
Fundamentally you need classic decimal printing using digit production by dividing your number by ten (in your base 2^32) repeatedly and using the remainder as digits. You may not have a divide by (anything, let alone) 10 routine, which is probably the key source of your problem.
If you are working in C or C++, you can get a complete infinite precision arithmetic package from GNU Bignum package. Most other widely used languages have similar packages available.
Of course, if you have too much free time, you can always implement multiprecision division yourself. You're already borrowing terminology from Knuth; he also supplies the multiprecision algorithms in Seminumerical Algorithms.
If it is .NET, take a look at this implementation of a BigInteger class.
How about using long doubles? Then you get 80bits in the mantissa, but I guess that the accuracy is lost when using floating point numbers.

Resources