Проблема с генератором чисел(с использование библиотек gmp mpir)

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Trilgon, 27 Jul 2017.

  1. Trilgon

    Trilgon New Member

    Joined:
    5 Jul 2017
    Messages:
    32
    Likes Received:
    0
    Reputations:
    0
    Примерно 4 дня назад решил ознакомиться со сторонними библиотеками для C++.После того как я более менее разобрался в них,
    я решил написать какую-нибудь программу используя их возможности(если быть точным плавающей поплавок),я размышлял,что бы лучше написать в меру тяжёлое,но и не слишком лёгкое и решил написать генератор чисел с 30 знаками после запятой для нуля (например,0.011112345678987654321234567897 и т.п),так как решил,что такой генератор возможно пригодится мне,ну если нет,то всё равно я смогу набраться некоторого опыта,однако столкнулся с некой проблемой,а именно,то что показывается число отличающиеся от того которое я вводил.
    Код программы:
    Code:
    #include "stdafx.h"
    #include<gmpxx.h>
    #include<stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include<mpirxx.h>
    #include <mpir.h>
    #pragma comment(lib, "mpir.lib")
    int main()
    {
    mpf_t x, y;
    mpf_set_default_prec(56);
    mpf_init(x);
    mpf_init(y);
    mpf_set_ui(y,1000000000000000000000000000000.0);
    for (unsigned long i = 10000000000000000000000000000.0; i <= 19999999999999999999999999999.0; ++i)
    {
    mpf_set_ui(x,i);
    mpf_div(x, x, y);
    gmp_printf("%.*Ff x\n",30,x,1);
    }
    mpf_clear(x);
    mpf_clear(y);
    getchar();
    return 0;
    }
    
    При запуске пишет следующее:
    1>------ Построение всех файлов начато: проект: ConsoleApplication4, Конфигурация: Release x64 ------
    1>ConsoleApplication4.cpp
    1>ConsoleApplication4.cpp(15): warning C4244: аргумент: преобразование "double" в "mpir_ui", возможна потеря данных
    1>ConsoleApplication4.cpp(15): warning C4056: переполнение при арифметических операциях с константой с плавающей точкой
    1>ConsoleApplication4.cpp(16): warning C4244: инициализация: преобразование "double" в "unsigned long", возможна потеря данных
    1>ConsoleApplication4.cpp(16): warning C4056: переполнение при арифметических операциях с константой с плавающей точкой
    1>stdafx.cpp
    1>LINK : warning LNK4098: библиотека по умолчанию "LIBCMT" противоречит использованию других библиотек; используйте параметр /NODEFAULTLIB:library
    1>Создание кода
    1>All 1 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
    1>Создание кода завершено
    1>ConsoleApplication4.vcxproj -> C:\Users\R2BDO\Documents\Visual Studio 2017\Projects\ConsoleApplication4\x64\Release\Cons oleApplication4.exe
    1>Сборка проекта "ConsoleApplication4.vcxproj" завершена.
    ========== Перестроение всех проектов: успешно: 1, с ошибками: 0, пропущено: 0 ==========
    Результат работы программы:
    0.000000000000000000000000000000 x
    0.000000000000000000196968103277 x
    0.000000000000000000393936206553 x
    0.000000000000000000590904309830 x
    0.000000000000000000787872413107 x
    0.000000000000000000984840516383 x
    0.000000000000000001181808619660 x
    0.000000000000000001378776722936 x
    0.000000000000000001575744826213 x
    0.000000000000000001772712929490 x
    0.000000000000000001969681032766 x
    0.000000000000000002166649136043 x
    0.000000000000000002363617239320 x
    0.000000000000000002560585342596 x
    0.000000000000000002757553445873 x
    0.000000000000000002954521549149 x
    И так далее...
    Суть проблемы в том,что генерироваться числа таким образом будут очень долго,именно поэтому я пытался присвоить большое значение самого начала,однако не вышло.Пробовал читать документацию(http://www.mpir.org/mpir-3.0.0.pdf),но так и не нашёл решения.
     
  2. neviens

    neviens Member

    Joined:
    9 Oct 2013
    Messages:
    82
    Likes Received:
    28
    Reputations:
    3
    Code:
    ...
    int main()
    {
       mpf_t divident, divisor, result, lim, delta;
       
       mpf_set_default_prec(128);
       mpf_init_set_str(divident, "1000000000000000000000000000000e0", 10);
       mpf_init_set_str(divisor,  "1000000000000000000000000000000e0", 10);
       mpf_init_set_str(lim,  "1000000000000000000000000000009e0", 10);
       mpf_init(result);
    
       for(mpf_init_set_ui(delta, 1); mpf_cmp(divident, lim) <= 0; mpf_add(divident, divident, delta))
       {
         mpf_div(result, divident, divisor);
         gmp_printf("%.Ff\n", result);
       }
    
       mpf_clear(divident);
       mpf_clear(divisor);
       mpf_clear(result);
       mpf_clear(lim);
       mpf_clear(delta);
       getchar();
       return 0;
    }
     
    Trilgon likes this.