Преобразование восьмеричных чисел в десятичные в C

#include <stdio.h>
#include <math.h>

void main() {
    long int on, temp;
    int dn = 0, e = 0, digit;
    printf("Enter octal number : ");
    scanf("%ld", &on);
    temp = on;
    while (on != 0) {
        digit = on % 10;
        dn += digit * pow(8, e);
        e++;
        on /= 10;
    }
    printf("octal number = %ld \n", temp);
    printf("Decimal number= %d  \n", dn);

    return 1;
}

Привет, добрый день. У меня есть этот код для преобразования восьмеричных чисел в десятичные, но мой вопрос/проблема в том, как сделать код, который будет преобразовывать восьмеричные десятичные числа. Пример:

0,758 → ___10

0,000018 → ___10

при преобразовании вы должны умножить каждую цифру на квадрат 8 (8,64,542...)

Мне нужна помощь в этом.


person Horlic Vince    schedule 22.09.2015    source источник
comment
Сначала сделайте отступ в коде, пожалуйста   -  person Thomas Ayoub    schedule 22.09.2015
comment
Вы смешиваете вещи. Восьмеричное, шестнадцатеричное и т. д. являются возможными представлениями целых чисел внутри строк. Как только число сохраняется как таковое, оно является двоичным, и вы не увидите никакой разницы в том, как была внешняя кодировка внутри строки.   -  person Jens Gustedt    schedule 22.09.2015


Ответы (4)


Не делай этого так.

Считайте данные от пользователя в буфер char*.

Затем используйте strtoul(); указание основания 8.

person Community    schedule 22.09.2015
comment
Затем используйте printf("%o", n);, чтобы отобразить восьмеричное число. - person Bart Friederichs; 22.09.2015
comment
Я отрицаю этот ответ, потому что он не касается иррациональных чисел на сложной плоскости произвольной точности. - person r3mainer; 23.09.2015
comment
Ха-ха! Я полностью уважаю ваше решение. Черт, теперь у меня больше нет достаточной репутации, чтобы комментировать ваш ответ, за который я только что проголосовал. - person ; 23.09.2015
comment
char* буфер. -› массив символов. - person chqrlie; 26.02.2017

Вот программа, которая вводит дробное восьмеричное число и преобразует его в значение с плавающей запятой. Восьмеричная точка и хотя бы одна следующая за ней цифра обязательны, поэтому не ожидайте, что это сработает с такими входными данными, как "100" или "100".

#include <stdio.h>
int main() {
  unsigned int integer_part, fraction_part, len1, len2;
  double result;
  scanf("%o.%n%o%n", &integer_part, &len1, &fraction_part, &len2);
  result = fraction_part * 1.0 / (1<<(len2-len1)*3);
  result += integer_part;
  printf("%.6f\n",result);
  return 0;
}

Примеры:

$ ./oct <<<"0.75"
0.953125
$ ./oct <<<"100.1"
64.125000

Если вы хотите принимать более широкий диапазон входных данных (включая целые числа), вам лучше прочитать целую строку текста и разобрать ее по частям.

person r3mainer    schedule 22.09.2015
comment
Это правильный ответ. Другие не обращаются к дробным числам. - person dbush; 22.09.2015
comment
Нет, это не так: он не обращается к иррациональным числам на комплексной плоскости произвольной точности. OP явно нужны целые числа, иначе они выбрали бы другой тип данных. Это вопрос о том, где вы проводите линию, чтобы ответить. Возможно, так правильнее. Но это не совсем правильно. - person ; 23.09.2015
comment
Для спецификатора формата %n требуется int *. len1 и len2 должны быть определены как int. - person chqrlie; 26.02.2017
comment
(1<<(len2-len1)*3) может легко переполниться. Вы должны хотя бы написать (1ULL << ((len2 - len1) * 3)). Гораздо безопаснее использовать ldexp и frexp. - person chqrlie; 26.02.2017

Вы можете читать данные в восьмеричном формате.

#include<stdio.h>
#include<math.h>
int main()
{
    unsigned on;
    printf("Enter octal number : ");
    scanf("%o",&on);
    printf("octal number = %o \n",on);
    printf("Decimal number= %d  \n",on);
    return 0;
}

Буквально то, как вы читаете данные или показываете данные, зависит от вас, внутреннее представление одинаково для всех шестнадцатеричных, восьмеричных и десятичных. Для дальнейшего чтения см.

person ashiquzzaman33    schedule 22.09.2015
comment
Вы должны использовать %u вместо unsigned on в десятичном формате. - person chqrlie; 26.02.2017

Если нужно справиться с дробным вводом, таким как строка «123,456», представляющая восьмеричное число и имеющая десятичное значение 83.589843750, тогда читайте целую (целую) числовую часть и дробную часть как целые числа отдельно: каждое целое число из строки восьмеричного числа цифры.

Хорошее время для повторного использования кода, так что создайте вспомогательную функцию. Код может использовать unsigned on; scanf("%o",&on); или код, подобный приведенному ниже.

Часть дроби немного сложна. Код ниже «делит» каждую дробную цифру на 8 с умножением 1000/8 и делением на 1000 (путем печати групп из 3 цифр справа от .).

#include <stdio.h>
#include <limits.h>
#include <stdint.h>

static int ReadOctal(uintmax_t *octal, unsigned *count) {
  int ch;
  *octal = 0;
  *count = 0;
  while ((ch=fgetc(stdin)) >= '0' && ch <= '7') {
    (*count)++;
    if (*octal > UINTMAX_MAX/8) puts("Overflow");
    *octal = *octal*8 + (unsigned)(ch - '0');
  }
  return ch;
}

void octal_decimal(void) {
  uintmax_t ipart;
  uintmax_t fpart = 0;
  unsigned count;
  int ch = ReadOctal(&ipart, &count);
  if (ch == '.') {
    ReadOctal(&fpart, &count);
  }
  printf("%ju", ipart);
  if (ch == '.') {
    for (unsigned i=0; i<count; i++) {
      if (fpart > UINTMAX_MAX/(1000/8)) puts("Overflow");
      fpart *= 1000/8;
    }
    printf(".%0*ju", count*3, fpart);
  }
  puts("");
}

123.456 // input
83.589843750 // output
person chux - Reinstate Monica    schedule 22.09.2015