4

I was trying to solve Project Euler's 25th (https://projecteuler.net/problem=25) problem in Swift and got a pretty cryptical error message when I changed my condition in the while loop.

At first, I started with 2, and then 10 and got the right results. But then with 100, the program crashed.

var index = 3
var a = 1
var b = 2

while String(b).characters.count < 100 {
  let temp = b
  b = a + b
  a = temp
  index += 1
}

print(index)

This is the error:

0  swift                    0x00000001103b24f7 PrintStackTraceSignalHandler(void*) + 39
1  swift                    0x00000001103b19a6 SignalHandler(int) + 646
2  libsystem_platform.dylib 0x00007fffb3a89b3a _sigtramp + 26
3  libswiftCore.dylib       0x0000000112d6a40d (anonymous namespace)::Sentinels + 12861
4  swift                    0x000000010dcfadcf llvm::MCJIT::runFunction(llvm::Function*, llvm::ArrayRef<llvm::GenericValue>) + 655
5  swift                    0x000000010dd009c3 llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, char const* const*) + 707
6  swift                    0x000000010d1fdc69 swift::RunImmediately(swift::CompilerInstance&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, swift::IRGenOptions&, swift::SILOptions const&) + 3385
7  swift                    0x000000010d1d2622 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 50738
8  swift                    0x000000010d17fd6c main + 9052
9  libdyld.dylib            0x00007fffb387a235 start + 1
Stack dump:
0.  Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -interpret ./project-euler/025/problem025.swift -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -color-diagnostics -module-name problem025 
[1]    8705 illegal hardware instruction  ./project-euler/025/problem025.swift

Does anyone have any idea why this is happening? The exact same code runs smoothly in Python and Ruby.

Frank Kair
  • 451
  • 4
  • 13
  • 1
    That is an integer overflow. Similar questions: https://stackoverflow.com/q/34707568/1187415, https://stackoverflow.com/q/31317369/1187415, https://stackoverflow.com/q/40345093/1187415. – You cannot store a 100 (or 1000) digit number in an `Int` – Martin R Aug 19 '17 at 18:30
  • Or anywhere for that matter. – matt Aug 19 '17 at 18:32

2 Answers2

1

Your algorithm is right, but the problem is that Swift 64 bit integers can only hold values up to 9,223,372,036,854,775,807, i.e. 9.22e+18. Unsigned integers can be twice as large, but still nowhere close to 1,000 digits. Decimal/NSDecimalNumber gets you up to 38 digits, which still is not sufficient.

You probably want to create/use a library that can represent arbitrarily large integers. Just search the interwebs for "swift arbitrarily large integer" or "swift biginteger".

Then your routine will correctly calculate the result.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

You could use a UInt64 if all your operations are positive, which they seem to be. That might prevent an overflow since you'll get a longer range.

rounak
  • 9,217
  • 3
  • 42
  • 59