Квадратный корень из величины с использованием GMP
Вопрос
Мне нужно точно извлечь квадратный корень из 210-значного числа, я подумал, что GMP - подходящий инструмент для этой работы, что я делаю не так?
#include <stdlib.h>
#include <stdio.h>
#include "gmp.h"
int
main (int argc, char *argv[])
{
mpz_t sq_me, sq_out, test;
mpz_init(sq_me);
mpz_init(sq_out);
mpz_init(test);
mpz_set_str (sq_me, argv[1], 10);
mpz_sqrt(sq_out, sq_me);
mpz_mul(test,sq_out,sq_out);
gmp_printf ("%Zd\n\n", sq_out);
gmp_printf ("%Zd\n\n", test);
return 0;
}
Входные данные:
24524664490027821197651766357308801846702678767833275974341445171506160083003858 72169522083993320715491036268271916798640797767232430056005920356312465612184658 17904100131859299619933817012149335034875870551067
Выходной сигнал:
49522383313031109809242226159886283348695660460381271324714928680654813093947239 9634016783775955618921028
24524664490027821197651766357308801846702678767833275974341445171506160083003858 72169522083993320715491034366358025027526868495267716284867043049443779615862887 47102011391915422793532619329760963626718900576784
Решение
Вот код, который вам нужен для вычисления квадратного корня с плавающей запятой, вы можете видеть, что начальный ввод и конечный вывод идентичны.
#include <stdlib.h>
#include <stdio.h>
#include "gmp.h"
int main (int argc, char *argv[]) {
mpf_t sq_me, sq_out, test;
mpf_set_default_prec (10000);
mpf_init(sq_me);
mpf_init(sq_out);
mpf_init(test);
mpf_set_str (sq_me, argv[1], 10);
mpf_sqrt(sq_out, sq_me);
mpf_mul(test,sq_out,sq_out);
gmp_printf ("Input: %Ff\n\n", sq_me);
gmp_printf ("Square root: %.200Ff\n\n", sq_out);
gmp_printf ("Re-squared: %Ff\n\n", test);
return 0;
}
Вот выходные данные с вашим параметром:
Input: 2452466449002782119765176635730880184670267876783327597434144
51715061600830038587216952208399332071549103626827191679864079776723243005
60059203563124656121846581790410013185929961993381701214933503487587055106
7.000000
Square root: 4952238331303110980924222615988628334869566046038127132471492
86806548130939472399634016783775955618921028.19202568258368255653837168412
92356432661548614332014106174638951390596672950394981098992388116308833260
04535647648563996144250924277757344248059826024201642748515325655438898558
17807282091590722890002
Re-squared: 2452466449002782119765176635730880184670267876783327597434144
51715061600830038587216952208399332071549103626827191679864079776723243005
60059203563124656121846581790410013185929961993381701214933503487587055106
7.000000
Другие советы
Вы получаете результат в виде целого числа, а затем возводите его в квадрат.Входное число не должно быть идеальным квадратом, поэтому оно усекает десятичные дроби и уменьшает точность числа.Посмотрите на категорию функций 'mpf' для чисел с плавающей точкой, а не 'mpz' для целых чисел.
Я использую libgmp-3.dll
В vb.net Я написал эту функцию для получения квадратного корня высокой точности.Я не тестировал его тщательно, но он дает мне квадратный корень из 3 с любой точностью, которая мне нужна
Public Shared Function SquareRoot(ByVal Value As BigInt, ByVal Precision As Integer) As String
Dim Ten As New BigInt(10)
Dim DecLen As Integer = Value.Sqrt.ToString.Length
Dim RootDigits As String = (Value * Ten.Power(Precision * 2)).Sqrt
'Add trailing zeros
RootDigits = RootDigits.PadRight((DecLen + Precision), "0")
Return RootDigits.Substring(0, DecLen) & "." & RootDigits.Substring(DecLen)
End Function