jacknpoe

Converte um double em string (até 18 casas)

Nov 12th, 2025 (edited)
560
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.32 KB | None | 0 0
  1. // conversão de números double em char*
  2. // Versão: 0.1: 18/09/2025: inicial, funcional e para zeros e menores que 1
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdbool.h>
  8.  
  9. #define TAMANHOBUFFER 20   // esse é o tamanho do "buffer" de doubletostr (não contando com o caracter ASCII(0)) [é limitado ao tamanho de unsigned long long]
  10.  
  11. // essa função de exponenciação é especial para expoentes inteiros
  12. double power_int(double base, int expoente) {
  13.     if (expoente < 0) return power_int(1 / base, expoente * -1);   // quando "expoente" é negativo, o resultado é 1 / "base" elevado ao valor absoluto do "expoente"
  14.     if (expoente == 0) return 1;   // quando "expoente" é zero, o resultado é um
  15.     if (expoente % 2 == 0) return power_int(base * base, expoente / 2);   // quando "expoente" é divisível por dois, o resultado é "base"² elevado ao "expoente" / 2
  16.     return base * power_int(base * base, (expoente - 1) / 2);    // quando "expoente" não é divisível por dois, o resultado é "base" * ("base"² elevado a ("expoente" - 1) / 2)
  17. }
  18.  
  19. // essa função converte um double "valor" em um char* com o número de "casas" decimais
  20. // "casas" não pode ser maior do que 18, porque senão sai lixo
  21. // funciona quando os dígitos vão até próximo a 9.223.372.036.854.775.807 por causa da conversão entre double e unsigned long long
  22. char* doubletostr(double valor, int casas) {
  23.     if (casas > 18) casas = 18;   // depois de 18, estoura digitos (mas veja que, na prática, só tem precisão de 15 a 17 casas)
  24.     unsigned long long digitos = valor * power_int(10.0, casas) + 0.5;   // aqui, criamos um inteiro com os "digitos" rotacionados por "casas"
  25.     char buffer[TAMANHOBUFFER + 1];   // "buffer" guardará o char* enquanto digitos ainda estiver sendo utilizado
  26.     char* retorno;   // no final, esse ponteiro apontará para uma localização na memória alocada dinamicamente com o resultado
  27.     buffer[TAMANHOBUFFER] = 0;   // inserimos o marcador de final do char* na posição final do "buffer"
  28.     int atual = TAMANHOBUFFER - 1;   // o primeiro dígito (a partir da direita) será na posição anterior ao final do "buffer"
  29.  
  30.     while (atual >= 0 && (digitos > 0 || (casas > 0 && atual + casas >= TAMANHOBUFFER - 1 ))) {   // enquanto houver dígitos e espaço no buffer, iremos processar os dígitos
  31.         buffer[atual] = '0' + digitos % 10;   // pega o dígito mais a direita que ainda estiver em "digitos" e coloca em "buffer"
  32.         digitos = digitos / 10;   // retira o dígito mais à direita (dividir por zero um inteiro faz exatamente isso)
  33.         atual--;   // movemos a posição atual no "buffer" um dígito
  34.         if (atual + casas == TAMANHOBUFFER - 1 && atual >= 0 && casas > 0) {   // verificamos se agora é para colocar a vírgula no lugar
  35.             buffer[atual] = ',';   // coloca a vírgula na posição atual
  36.             atual--;   // move a posição atual no "buffer" uma vírgula
  37.             if (digitos == 0) {   // se, antes da vírgula, não existirem mais dígitos
  38.                 buffer[atual] = '0';   // coloca um zero antes da vírgula
  39.                 atual--;   // move a posição atual no "buffer" uma vírgula
  40.             }
  41.         }
  42.     }
  43.  
  44.     if (atual == TAMANHOBUFFER - 1) {   // se o número for 0
  45.         buffer[atual] = '0';   // inclui o 0
  46.         atual--;   // move a posição atual
  47.     }
  48.  
  49.     retorno = (char*) malloc((TAMANHOBUFFER - atual) * sizeof(char));   // agora alocamos dinamicamente para poder ser resultado da função
  50.     if (retorno == NULL) return NULL;   // se não conseguir alocar, retorna NULL (embora, na prática, isso nunca deve acontecer)
  51.     strcpy(retorno, buffer + atual + 1);   // copia apenas os dígitos (e eventual vírgula) para o char* alocado dinamicamente
  52.  
  53.     return retorno;   // retorna o char* alocado dimamicamente
  54. }
  55.  
  56. int main() {
  57.     printf("Potência: %f\n", power_int(10.0, 15));
  58.     printf("Extenso: %s\n", doubletostr(123.45678905, 7));
  59.     printf("Extenso: %s\n", doubletostr(123.45, 10));
  60.     printf("Extenso: %s\n", doubletostr(123.45, 1));
  61.     printf("Extenso: %s\n", doubletostr(0.000123, 10));
  62.     printf("Extenso: %s\n", doubletostr(1.12345678901234567890, 19));
  63.     printf("Extenso: %s\n", doubletostr(9223372036854775807, 0));
  64.     printf("Extenso: %s\n", doubletostr(123456789012345678.9, 1));
  65.     return 0;
  66. }
  67.  
Tags: Conversão
Advertisement
Add Comment
Please, Sign In to add comment