Home > Blockchain >  How do you shorten numbers with a lot of 0s?
How do you shorten numbers with a lot of 0s?

Time:02-27

I was wondering how I would shorten numbers, for example 10000000000 (ten 0s), to something shorter like 1e10, and how to implement this into my code. This is my current code:

do
{
    card_num = get_long("Number: ");
}
while (card_num < 0);

num1 = ((card_num % 100) / 10) * 2;
num2 = ((card_num % 10000) / 1000) * 2;
num3 = ((card_num % 1000000) / 100000) * 2;
num4 = ((card_num % 100000000) / 10000000) * 2;
num5 = ((card_num % 10000000000) / 1000000000) * 2;
num6 = ((card_num % 1000000000000) / 100000000000) * 2;
num7 = ((card_num % 100000000000000) / 10000000000000) * 2;
num8 = ((card_num % 10000000000000000) / 1000000000000000) * 2;

This is what I want it to look like (or similar):

do
{
    card_num = get_long("Number: ");
}
while (card_num < 0);

num1 = ((card_num % (1e2) / 1e1) * 2;
num2 = ((card_num % 1e4) / 1e3) * 2;
num3 = ((card_num % 1e6) / 1e5) * 2;
num4 = ((card_num % 1e8) / 1e7) * 2;
num5 = ((card_num % 1e10) / 1e9) * 2;
num6 = ((card_num % 1e12) / 1e11) * 2;
num7 = ((card_num % 1e14) / 1e13) * 2;
num8 = ((card_num % 1e16) / 1e15) * 2;

But this is the error message that I get:

credit.c:25:25: error: expected expression
    num1 = ((card_num % long(1e2) / 1e1) * 2;
                        ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
2 errors generated.
make: *** [<builtin>: credit] Error 1

How do I fix this?

CodePudding user response:

#define KILO 1000U
#define KIBI 1024U
#define MEGA 1000000LLU
#define MEBI 1048576LLU
#define GIGA 1000000000LLU
#define GIBI 1073741824LLU

int a = 42 * KILO;
int b = -1 * MEGA;
long long unsigned mem = 24 * GIBI; // my machine has 24GBytes

kibi, mebi, gibi are the corresponding binary prefixes to kilo, mega, giga

CodePudding user response:

To add to @pmg's solution (with @chux's comment considered):

#define KB *1024
#define MB *1048576
#define GB *1073741824
// ...

Or:

#define KB *1000
#define MB *1000000
#define GB *1000000000
// ...

Example code:

printf("%ld", 1 MB); // 1048576 or 1000000
printf("%ld", 8 GB); // 8589934592 or 8000000000

This is far from a perfect solution, but if you want to avoid macros, you can use this function:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

long exp_notation(const char *number)
{
    char *expo = strchr(number, 'e');
    if (!expo)
        return -1;
    
    const char *p = number;
    long ret = 0;
    long ex = 0;
    
    // Numbers before e
    for (; p != expo;   p) {
        if (!isdigit(*p))
            return -1;
        
        ret *= 10;
        ret  = *p - 48;
    }
    
    // Numbers after e
    for (p = expo 1; *p;   p) {
        if (!isdigit(*p))
            return -1;
        
        ex *= 10;
        ex  = *p - 48;
    }
    
    while (ex--)
        ret *= 10;
    
    return ret;
}

int main(void)
{
    printf("%ld\n", exp_notation("45e9")); // 45000000000
}

If the e doesn't exist in the input, it returns -1. Just make sure you pass the correct input.

EDIT: AS pointed by @chux, ff you are under a 32-bit machine then something like 8 GB will cause an undefined behaviour. See here and here to know which architecture your code is running on.

  • Related