A story about an arithmetic overflow that you shouldn't encounter in Ruby

Introduction

The author, who mainly uses Ruby, encountered an arithmetic overflow and learned lessons, so I will share the situation and countermeasures that occurred. ** * There is no math problem this time ... **

And thank you for the wide variety of Tribonatch and comments! Among them, I would like to introduce an article by @torifukukaiou who solved Tribonatch with the Elixir version. [I tried to solve the tribonacci sequence problem with Elixir (time limit 10 minutes)] (https://qiita.com/torifukukaiou/items/d5a6639edf541539ac3a?utm_campaign=email&utm_content=link&utm_medium=email&utm_source=public_mention)

What were you trying to do?

A few days have passed since the last battle with the Tribonacci sequence, and I was looking for a way to speed up the implementation in order to solve even more intense math problems in the future. Meanwhile, I learned that C language can be used with gem'RubyInline', and when I implemented it to touch C language a little, an arithmetic overflow error occurred.

About the flow until the occurrence of arithmetic overflow

I created a directory and rb file with the following command, opened VS Code and edited it.

$ cd Desktop
$ mkdir Ruby_with_c
$ cd Ruby_with_c
$ touch tribonacci.rb
$ bundle init
$ code .

Write gem'RubyInline','~> 3.12','> = 3.12.4' in Gemfile and bundle install

Gemfile


# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
gem 'RubyInline', '~> 3.12', '>= 3.12.4'
$ bundle install

Kakikaki the code ... (How do you write it in C ... ´ · ௰ · `) ← What did you do? (゚ Д ゚) I wrote it because it can be easy for the time being! !!

tribonacci.rb


require 'inline'

class Tribonacci
  inline do |builder|
    builder.c "
      int add(int a, int b, int c){
        int d,i = 3;
        while (i<50){
          d = a + b + c;
          a = b;
          b = c;
          c = d;
          i++;
        }
        return c;
      }
    "
  end
end

puts Tribonacci.new.add(1,3,7)

The above code is the same as the code implemented to solve the tribonatch sequence in Ruby. However, if implemented with this code, ** arithmetic overflow will occur and the calculation result will be negative **.

Commentary

You can write external code (C language) in Ruby code by writing require'inline' on the first line. The int type data type is defined for each int description on the 6th line. However, this gives an outlier with a negative display from the 36th answer in the Tribonacci sequence.

35th answer 1831177831 36th answer-926906165

This phenomenon is called ** Arithmetic Overflow **. In C language, the processing system that becomes the minimum value LONG_MIN (-2147483648) when the maximum value of int INT_MAX (2147483647) is exceeded by 1 is being implemented. In this implementation, it seems that the 36th item exceeded INT_MAX (2147483647) and started from -2147483648.

To prevent arithmetic overflow, change from int to long this time. long maximum value: 9223372036854775807

tribonacci.rb


require 'inline'

class Tribonacci
  inline do |builder|
    builder.c "
      long add(long a, long b, long c){
        long d,i = 3;
        while (i<50){
          d = a + b + c;
          a = b;
          b = c;
          c = d;
          i++;
        }
        return c;
      }
    "
  end
end

puts Tribonacci.new.add(1,3,7)

By changing to long, the 36th 3368061131 comes out. By the way, Ruby integers are automatically expanded in number of digits, so there is no arithmetic overflow. So if I only touched Ruby, I wouldn't encounter arithmetic overflow. Thank you for meeting! !!

in conclusion

After just touching C language for a while, I encountered an error that I didn't encounter in Ruby and learned a lot. Currently, I was only able to introduce the gem'RubyInline', but in the future I would like to create an extension library for C language and implement high-speed processing to solve intense mathematical problems.

bonus

If anyone has an interesting math problem, please leave it in the comments! !! The process of solving was very educational and I was addicted to math problems. Based on the spirit of Connecting the dots, I will continue to do my best, believing that the days of immersion will shine someday!

Recommended Posts

A story about an arithmetic overflow that you shouldn't encounter in Ruby
A story about converting character codes from UTF-8 to Shift-jis in Ruby
A story about the JDK in the Java 11 era
A story about a very useful Ruby Struct class
A story about making a Builder that inherits the Builder
A story about saving an image with carrierwave in a nested form using a form object.
A story about creating a library that operates next-generation sequencer data with Ruby ruby-htslib
A story that got stuck with an error during migration in docker PHP laravel
A small story that is sometimes useful in Maven
About eval in Ruby
I made an interpreter (compiler?) With about 80 lines in Ruby.
Determine that the value is a multiple of 〇 in Ruby
How to change a string in an array to a number in Ruby
A story about BeanNotOfRequiredTypeException occurring after applying AOP in Spring
In Ruby you can define a method with any name
[Docker] The story that an error occurred in docker-compose up
A story that a Ruby beginner made and released a LINE BOT that tells the train time in 2 months
Multiplication in a Ruby array
About regular expressions in Ruby
[Ruby] I want to put an array in a variable. I want to convert to an array
The story that Tomcat suffered from a timeout error in Eclipse
[Ruby] Use an external API that returns JSON in HTTP request
A story about writing a ratio calculation at an in-house study session
When you receive a call, send an SMS to that number
Creating an ArrayList that allows you to throw in and retrieve the coordinates of a two-dimensional plane