Как решить факториал над номером 20 в параметре? [Дубликат]

См. источник грани , который использует getBoundingClientRect . Это как:

function inViewport (el) {

    var r, html;
    if ( !el || 1 !== el.nodeType ) { return false; }
    html = document.documentElement;
    r = el.getBoundingClientRect();

    return ( !!r 
      && r.bottom >= 0 
      && r.right >= 0 
      && r.top <= html.clientHeight 
      && r.left <= html.clientWidth 
    );

}

Возвращает true, если какая-либо часть элемента находится в окне просмотра.

2
задан BLUEPIXY 23 May 2016 в 17:58
поделиться

4 ответа

50! - очень большое число (более 60 цифр), а 2^64 меньше 50!. Причина, по которой вы не получаете правильное число, заключается в том, что вы получаете overflow , вы считаете выше предела того, что может вычислить ваш компьютер.

enter n 50
-3258495067890909184

Если у вас есть 64-разрядное целое число, наибольшее значение, которое оно может представлять, равно 2 ^ 64, для которого я меньше 50 !. Поэтому вы получаете переполнение.

Обычно в этих ситуациях вы прибегаете к некоторому трюку, похожим на 4-битную систему с 8-битным кодом, удваивая количество инструкций на слово (путь Intels first CPU имеет 8-битный код).

Таким образом, ваша 64-битная система может обрабатывать 128-битные слова, вам просто нужно написать алгоритм, который помещает данные в «куски», чтобы вы могли удвоить длину слова.

0
ответ дан Niklas Rosencrantz 24 August 2018 в 01:16
поделиться

50! - 30414093201713378043612608166064768844377641568960512000000000000 или около 3.04e+64, 215-битное число. Это значение обычно превышает диапазон типов, например long. Даже uintmax_t и unsigned long long необходимо только иметь возможность представлять по меньшей мере 64-битные целые числа.

long int fact(long int n) {
  ...
  // Overflows!
  return n*fact(n-1);

Чтобы получить точный ответ, код может использовать альтернативные типы. Следующее использует строковое / десятичное представление целого числа. Он работает при больших значениях n, так как правильная функциональность ограничена размером буфера.

char *strfact_mult(char *s, unsigned x) {
  unsigned sum = 0;
  size_t len = strlen(s);
  size_t i = len;
  while (i > 0) {
    sum += (s[--i] - '0')*x;
    s[i] = sum%10 + '0';
    sum /= 10;
  }
  while (sum) {
    len++;
    memmove(&s[1], s, len);
    s[i] = sum%10 + '0';
    sum /= 10;
  }
  return s;
}

char *str_fact(char *dest, unsigned n) {
  strcpy(dest, "1");
  while (n > 1) {
    strfact_mult(dest, n--);
  }
  return dest;
}

int main(void) {
  char buf[1000];
  puts(str_fact(buf, 0));
  puts(str_fact(buf, 1));
  puts(str_fact(buf, 5));
  puts(str_fact(buf, 50));
}

Выход

1
1
120
30414093201713378043612608166064768844377641568960512000000000000
1
ответ дан chux 24 August 2018 в 01:16
поделиться

Он не будет работать со стандартными типами C, вам нужно что-то еще (может быть, строка). Посмотрите на http://onlinemschool.com/math/formula/factorial_table/

Как видите, это довольно большое число.

0
ответ дан Ofir Sadeh 24 August 2018 в 01:16
поделиться
/* program to calculate large factorials with exact precision

   original program by chux, modified by ringzero
*/

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

char *strfact_mult(char *s, unsigned x)
{
    // modified code starts
    int len = strlen (s);
    int carry = 0;

    for ( int i = 1; i <= len; ++i ) {
        int product = (s[len - i] - '0') * x + carry;
        s[len - i] = product % 10 + '0';
        carry = 0;
        if ( product > 9 ) {
            carry = product / 10;
            if ( i == len ) {
                ++len;
                memmove (&s[1], s, len);
                s[0] = '0';
            }
        }
    }
    // modified code ends

    //unsigned sum = 0;
    //size_t len = strlen(s);
    //size_t i = len;
    //while (i > 0) {
    //  sum += (s[--i] - '0')*x;
    //  s[i] = sum%10 + '0';
    //  sum /= 10;
    //}
    //while (sum) {
    //  len++;
    //  memmove(&s[1], s, len);
    //  s[i] = sum%10 + '0';
    //  sum /= 10;
    //}

    return s;
}

char *str_fact(char *dest, unsigned n)
{
    strcpy(dest, "1");
    while (n > 1) {
      strfact_mult(dest, n--);
    }
    return dest;
}

int main (void)
{
    char buf[1000];
    puts(str_fact(buf, 0));
    puts(str_fact(buf, 1));
    puts(str_fact(buf, 5));
    puts(str_fact(buf, 50));
}
0
ответ дан ringzero 24 August 2018 в 01:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: