Hola, alguien sabe de algún método para calcular el resto de un numero natural de 200 digitos?, he intentado con gmp pero no me da la longitud.
Saludos.
no entiendo muy bien, pero parece interesante tu pregunta
Cita de: WHK en 23 Agosto 2016, 01:47 AM
Hola, alguien sabe de algún método para calcular el resto de un numero natural de 200 digitos?, he intentado con gmp pero no me da la longitud.
Saludos.
Creo que hay una manera mirando las ultimas cifras pero no estoy seguro de como, por ejemplo
758412364598471254368451126
MOD 2 = 0
ya que el ultimo digito ('6') es par.
La gracia esta en que solo evaluas unos digitos en lugar de todo el número.
claro, hace un tiempo hice ese tipo de ejercicios, por aritmetica modular
https://es.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/what-is-modular-arithmetic
https://es.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/congruence-modulo
epa programare haber si lo logro
Lo he logrado con php BC Math xD
http://php.net/manual/en/book.bc.php
Creo que gmp tiene un bug que no permite calcular la diferencia y resto de numeros mayores a 50 cifras, pero con bc math si pude :)
http://php.net/manual/en/function.bcmod.php
En .NET podrías haber utilizado la Class BigIntegers para realizar operaciones con números enteros:
Dim bigInt1 As BigInteger = BigInteger.Parse(String.Format("1{0}", New String("0"c, count:=199)))
' 10000000000000000000000000000000000000000000000000
' 00000000000000000000000000000000000000000000000000
' 00000000000000000000000000000000000000000000000000
' 00000000000000000000000000000000000000000000000000
Dim sum As BigInteger = (bigInt1 + 1)
Dim rest As BigInteger = (bigInt1 - 1)
Dim divide As BigInteger = BigInteger.Divide(bigInt1, New BigInteger(2))
Dim remainder As BigInteger = (bigInt1 Mod divide)
En el código te muestro ejemplos muy básicos, de parsing, de instanciación de la class, de la capacidad de utilización de operadores aritméticos convencionales (+/- Mod/C#: %), y la utilización de métodos aritméticos de la class.
Saludos
pero biginteger internamente es String
Cita de: -rn3w- en 23 Agosto 2016, 04:07 AMpero biginteger internamente es String
...No, en absoluto.
BigIntegers no trabaja internamente con
Strings, sino mayormente con arrays del tipo
Byte (
byte[]) como se puede verificar en el código fuente de la class
BigInteger y
BigNumber:
- BigInteger.cs Reference Source - .NET Framework 4.6.1 - Microsoft (http://referencesource.microsoft.com/#System.Numerics/System/Numerics/BigInteger.cs)
Obviamente el método
BigIntegers.ToString() representará el valor en formato de texto, pues esa es la finalidad de cualquier método que lleve por nombre "
ToString", del mismo modo que el método
BigIntegers.Parse tomará como parámetro un valor de texto para parsear, pero ese aspecto no tiene nada que ver con el funcionamiento interno del algoritmo, sino con una de las formas que se le facilita al usuario final (el programador) para utilizar la class y representarla. Aparte, el constructor de la class expone varios overloads que aceptan otros
datatypes distintos a
String, entre ellos los
datatypes numéricos convencionales y un array de
Byte.
Saludos
Aquí dejo un programa que hice en C para un problema de Project Euler. El programa calcula la suma total de los dígitos de factorial de 200 (en realidad, el ejercicio pedía de 100, pero puse 200 para que tuviera más de 200 dígitos). En el programa, para obtener los dígitos, tengo que sacar el módulo, así que funciona correctamente (lo digo porque Project Euler dictaminó que mi respuesta era buena).
#include <stdlib.h>
#include <stdio.h>
typedef struct {
unsigned char *bytes;
unsigned int num_bytes;
} big_int;
void set_big_int(big_int *result, unsigned char number);
void multiply(big_int *result, unsigned char number);
void divide(big_int *result, unsigned char denominator);
unsigned char get_module(big_int *result, unsigned char denominator);
void factorial(big_int *result, unsigned char number);
int is_zero(big_int *big_integer);
int main() {
big_int big_integer = {NULL, 0};
unsigned char digit;
unsigned int num_digits = 0;
unsigned int result = 0;
fprintf(stdout, "Adding all digits of 200!...\n");
factorial(&big_integer, 200);
while(is_zero(&big_integer) == 0) {
num_digits++;
digit = get_module(&big_integer, 10);
fputc(digit + '0', stdout);
result += digit;
divide(&big_integer, 10);
}
fprintf(stdout, "\n\nDigit sum result: %u\n", result);
fprintf(stdout, "Number of digits: %u", num_digits);
fgetc(stdin);
return 0;
}
void set_big_int(big_int *result, unsigned char number) {
if(result->bytes != NULL)
free(result->bytes);
result->bytes = malloc(sizeof(unsigned char));
result->bytes[0] = number;
result->num_bytes = 1;
}
void multiply(big_int *result, unsigned char number) {
register int i;
unsigned int rest = 0;
for(i = 0; i < result->num_bytes; i++) {
rest = result->bytes[i] * number + rest;
result->bytes[i] = rest & 0x000000FF;
rest >>= 8;
if(rest != 0 && i+1 == result->num_bytes) {
result->num_bytes += 1;
realloc(result->bytes, result->num_bytes);
result->bytes[i+1] = 0;
}
}
}
void divide(big_int *result, unsigned char denominator) {
register int i;
unsigned int module = 0;
unsigned int new_size = result->num_bytes;
for(i = result->num_bytes-1; i >= 0; i--) {
module = (unsigned int)result->bytes[i] + (module << 8);
result->bytes[i] = module/denominator;
module %= denominator;
}
for(i = result->num_bytes-1; i >= 0 && result->bytes[i] == 0; i--)
new_size--;
if(new_size != result->num_bytes) {
result->num_bytes = new_size;
realloc(result->bytes, new_size);
}
}
unsigned char get_module(big_int *result, unsigned char denominator) {
register int i;
unsigned int module = 0;
for(i = result->num_bytes-1; i >= 0; i--)
module = ((unsigned int)result->bytes[i] + (module << 8))%denominator;
return module;
}
void factorial(big_int *result, unsigned char number) {
unsigned char i;
set_big_int(result, 1);
for(i = 2; i <= number; i++)
multiply(result, i);
}
int is_zero(big_int *big_integer) {
register unsigned int i;
unsigned int result = 1;
for(i = 0; result == 1 && i < big_integer->num_bytes; i++)
result = big_integer->bytes[i] == 0;
return result;
}
Además, le he agregado para que imprima los dígitos en Little Endian, así que la salida del programa para calcular el factorial de 200 sería...
00000000000000000000000000000000000000000000000002747379830732698722222987169785
80071532604230714091306220668659755047521230423093757042424257723584928247221314
68192330452042466154126544229349889693732713367072758264311139928259426629160501
73624209724675203883691983121277140932648911048240302924330436994495344233524749
2362371786779531592260581239312363255305097463768756887
Digit sum result: 1404
Number of digits: 375