LINUX.ORG.RU

РЕШЕНО c++ и последовательность Фибоначчи

 , ,


0

0

Написал простейшую функцию, которая должна выводить на экран числа Фибоначчи. Но вот незадача - на экране месиво из непонятных чисел:

1644904672
1238694641
-1411367983
-172673342
-1584041325
-1756714667
954211304
-802503363
151707941
-650795422
-499087481
-1149882903
-1648970384
1496114009
-152856375
И ошибка: Ошибка сегментирования (стек памяти сброшен на диск) Пошустрив в интернетах нашел информацию, что при компилировании нужно выставлять ключ -fno-stack-protector но это, к сожалению, не помогло. Код ниже:
void fib() {
    int a[n];
    a[0] = 0;
    a[1] = 1;
    for (int i = 2; i <= n; i++) {
        a[i] = a[i-1] + a[i-2];
        cout << a[i] << endl;
    }
}
Решение ниже(Ахтунг, я сам не знаю как это работает, лучше это вообще не трогать):
#include <gmp.h>
#include <malloc.h>

int main() {
    mpz_t *a;
	int count = 10000, bits = 6912, i;
	a = (mpz_t*)malloc(count *sizeof(mpz_t));
	mpz_array_init(*a, count, bits);
    mpz_set_ui(a[0],0);
    mpz_set_ui(a[1],1);
	for(i = 2; i < count; ++i)  {
		mpz_add(a[i], a[i-1], a[i-2]);
        gmp_printf("%Zd\n", a[i]);
	}
}



Последнее исправление: RedMaun (всего исправлений: 9)

и белогривой лошадкой убежал указателем куда-то вдаль.

Avial ★★★★★
()

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

Esper
()
Ответ на: комментарий от RedMaun

Ну да, глупость какая-то. Переделаю.
int a[] = {0, 1};

час от часу не легче :) Ты создал массив на два элемента. Только на два, и не более. Думаю, намёк понятен? Это не JS. a[2] = 0 уже приведёт к нарушению стека и (возможно отложенному) падению.

former_anonymous ★★★
()

Ты объявил массив из 2 элементов, какие нахер 10000?!

anonymous
()

Может так?

#include <array>

using namespace std;

void fib() {
    const size_t count = 100;
    array<long, count> a = {0, 1}; 
    for (size_t i = 2; i <= count; ++i) {
        a[i] = a[i-1] + a[i-2];
        cout << a[i] << endl;
    }   
}

Кстати, сколько знаков у десятитысячного члена последовательности Фибоначчи?)

Rot1
()
Ответ на: комментарий от RedMaun

Массив в этой задаче сто лет не всрался, тут надо хранить только два элемента.

Если сильно хочется, в качестве расширяемого массива можно юзать вектор, добавляя элементы через push_back, или заранее бахнуть массив нужной длины, благо она известна сразу.

Esper
()
Ответ на: комментарий от Rot1

Так работает, но к концу появляются странные числа. Это из-за большого кол-ва знаков? Почему оно не может вывести нормальные числа в одну строчку?

RedMaun
() автор топика
Ответ на: комментарий от RedMaun

Почему оно не может вывести нормальные числа в одну строчку?

Не может вывести в одну строчку, потому что ты выводишь endl. Ты своим кодом требуешь выводить числа по одному на строку.

i-rinat ★★★★★
()
Ответ на: комментарий от RedMaun

И ничего с этим сделать нельзя?

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

former_anonymous ★★★
()
Ответ на: комментарий от former_anonymous

Десятитысячное число Фибоначчи равно 20 793 608 237 133 498 072 112 648 988 642 836 825 087 036 094 015 903 119 682 945 866 528 501 423 455 686 648 927 456 034 305 226 515 591 757 343 297 190 158 010 624 794 267 250 973 176 133 810 179 902 738 038 231 789 748 346 235 556 483 191 431 591 924 532 394 420 028 067 810 320 408 724 414 693 462 849 062 668 387 083 308 048 250 920 654 493 340 878 733 226 377 580 847 446 324 873 797 603 734 794 648 258 113 858 631 550 404 081 017 260 381 202 919 943 892 370 942 852 601 647 398 213 554 479 081 823 593 715 429 566 945 149 312 993 664 846 779 090 437 799 284 773 675 379 284 270 660 175 134 664 833 266 377 698 642 012 106 891 355 791 141 872 776 934 080 803 504 956 794 094 648 292 880 566 056 364 718 187 662 668 970 758 537 383 352 677 420 835 574 155 945 658 542 003 634 765 324 541 006 121 012 446 785 689 171 494 803 262 408 602 693 091 211 601 973 938 229 446 636 049 901 531 963 286 159 699 077 880 427 720 289 235 539 329 671 877 182 915 643 419 079 186 525 118 678 856 821 600 897 520 171 070 499 437 657 067 342 400 871 083 908 811 800 976 259 727 431 820 539 554 256 869 460 815 355 918 458 253 398 234 382 360 435 762 759 823 179 896 116 748 424 269 545 924 633 204 614 137 992 850 814 352 018 738 480 923 581 553 988 990 897 151 469 406 131 695 614 497 783 720 743 461 373 756 218 685 106 856 826 090 696 339 815 490 921 253 714 537 241 866 911 604 250 597 353 747 823 733 268 178 182 198 509 240 226 955 826 416 016 690 084 749 816 072 843 582 488 613 184 829 905 383 150 180 047 844 353 751 554 201 573 833 105 521 980 998 123 833 253 261 228 689 824 051 777 846 588 461 079 790 807 828 367 132 384 798 451 794 011 076 569 057 522 158 680 378 961 532 160 858 387 223 882 974 380 483 931 929 541 222 100 800 313 580 688 585 002 598 879 566 463 221 427 820 448 492 565 073 106 595 808 837 401 648 996 423 563 386 109 782 045 634 122 467 872 921 845 606 409 174 360 635 618 216 883 812 562 321 664 442 822 952 537 577 492 715 365 321 134 204 530 686 742 435 454 505 103 269 768 144 370 118 494 906 390 254 934 942 358 904 031 509 877 369 722 437 053 383 165 360 388 595 116 980 245 927 935 225 901 537 634 925 654 872 380 877 183 008 301 074 569 444 002 426 436 414 756 905 094 535 072 804 764 684 492 105 680 024 739 914 490 555 904 391 369 218 696 387 092 918 189 246 157 103 450 387 050 229 300 603 241 611 410 707 453 960 080 170 928 277 951 834 763 216 705 242 485 820 801 423 866 526 633 816 082 921 442 883 095 463 259 080 471 819 329 201 710 147 828 025 221 385 656 340 207 489 796 317 663 278 872 207 607 791 034 431 700 112 753 558 813 478 888 727 503 825 389 066 823 098 683 355 695 718 137 867 882 982 111 710 796 422 706 778 536 913 192 342 733 364 556 727 928 018 953 989 153 106 047 379 741 280 794 091 639 429 908 796 650 294 603 536 651 238 230 626.

Ему определённо не хватит __int128.

i-rinat ★★★★★
()
Последнее исправление: i-rinat (всего исправлений: 1)
Ответ на: комментарий от Rot1

В питоне целые числа могут быть произвольно большими.

сколько знаков у десятитысячного члена последовательности Фибоначчи

>>> len(str(fib(10000)))
2090
>>> len(str(2**6944))
2091
>>> 6944/8
868.0

Итого: число фибоначчи №1000 имеет 2090 цифр в десятичном представлении, в 6944 бита помещаются числа до 2091 цифры, надо не меньше 868 байт для 1000-го числа фибоначчи. В С++ нужна(ы) библиотека(и) для работы с такими большими числами.

arturianec100
()
Ответ на: комментарий от RedMaun
using T = unsigned __int128;
std::array<T, 100> a {1};
adjacent_difference(begin(a), std::prev(end(a)), std::next(begin(a)), std::plus<> {});

Тебе осталось придумать, как это вывести

Rot1
()
Ответ на: комментарий от arturianec100

В С++ нужна(ы) библиотека(и) для работы с такими большими числами.

C++ для реальных задач. Если тебе понадобилось больше ~30 десятичных знаков, ты либо что-то делаешь не так, либо ты математик.

Elyas ★★★★★
()
Ответ на: комментарий от arturianec100

Это так. Питонистам всегда жилось легче

Rot1
()
Ответ на: комментарий от i-rinat

Вот такое вроде справляется:

#include <boost/multiprecision/cpp_int.hpp>


void fib() {
    const size_t count = 10000;
    std::vector<boost::multiprecision::cpp_int> a = {0, 1}; 
    a.resize(count);
    for (size_t i = 2; i <= count; ++i) {
        a[i] = a[i-1] + a[i-2];
        std::cout << a[i] << "\n";
    }   
}
Kronick
()
Ответ на: комментарий от Kronick

У тебя, кстати, есть доступ к a[count], а в a всего count элементов. И как выше упоминали, можно делать a[i % 2] = a[0] + a[1]; и так сэкономить память. Смысла, правда, нет.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ну я код выше по треду взял и просто проверил работает ли с этим типом, я даже не смотрел особо. Похоже что работает, и раз Шон показывает что вычисляется даже с миллионным числом фибоначчи - значит все ок.

Хотя в документации и указано что: «The type uses a sign-magnitude representation internally, so type int128_t has 128-bits of precision plus an extra sign bit.»

Kronick
()
Ответ на: комментарий от arturianec100

Итого: число фибоначчи №1000 имеет 2090 цифр в десятичном представлении

Интересно, что число знаков в N-ом числе Фибоначчи асимптотически пропорционально N, а коэффициент пропорциональности --- десятичный логарифим золотого сечения

>>> from math import sqrt, log10
>>> phi = (1 + sqrt(5)) / 2
>>> 
>>> N = 10000
>>> len(str(fib(N)))
2090
>>> N*log10(phi)
2089.876402499787

Это следует из формулы Бине

Crocodoom ★★★★★
()
Ответ на: комментарий от Rot1

using T = unsigned __int128;
std::array<T, 100> a {1};
adjacent_difference(begin(a), std::prev(end(a)), >std::next(begin(a)), std::plus<> {});

Спасибо, но я по другому решил

RedMaun
() автор топика
Ответ на: комментарий от Elyas

Всегда казалось, что ъ-математикам вообще десятичные знаки не нужны, помимо наверное нескольких литералов.

anonymous
()
Ответ на: комментарий от lberserq

Нет, ошибка была из-за неправильно обьявленного массива.

RedMaun
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.