L'histoire de la rencontre d'un débordement arithmétique qui ne devrait pas être rencontré dans Ruby

introduction

L'auteur, qui utilise principalement Ruby, a rencontré un débordement arithmétique et a tiré des leçons, je vais donc partager la situation et les contre-mesures qui se sont produites. ** * Il n'y a pas de problème mathématique cette fois ... **

Et merci pour la grande variété de Tribonatch et de commentaires! Parmi eux, je voudrais vous présenter un article de @torifukukaiou qui a résolu Tribonacci avec la version Elixir. [J'ai essayé de résoudre le problème de la séquence tribonacci avec Elixir (délai de 10 minutes)] (https://qiita.com/torifukukaiou/items/d5a6639edf541539ac3a?utm_campaign=email&utm_content=link&utm_medium=email&utm_source=public_mention)

Qu'est ce que tu essayais de faire?

Quelques jours se sont écoulés depuis la dernière bataille avec la séquence Tribonacci, et je cherchais un moyen d'accélérer la mise en œuvre afin de résoudre des problèmes mathématiques encore plus intenses à l'avenir. Pendant ce temps, j'ai appris que le langage C peut être utilisé avec gem'RubyInline ', et quand je l'ai implémenté pour toucher un peu le langage C, une erreur de dépassement arithmétique s'est produite.

À propos du flux jusqu'à l'apparition d'un dépassement arithmétique

J'ai créé un répertoire et un fichier rb avec la commande suivante, ouvert VSCode et l'ai édité.

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

Écrivez gem'RubyInline ',' ~> 3.12 ','> = 3.12.4 'dans Gemfile et 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 le code ... (Comment l'écrivez-vous en langage C ... ´ · ௰ · `) ← Qu'as-tu fait? (゚ Д ゚) Je l'ai écrit parce que cela peut être facile pour le moment! !!

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)

Le code ci-dessus est le même que le code implémenté pour résoudre la séquence tribonatch dans Ruby. Cependant, s'il est implémenté avec ce code, ** un débordement arithmétique se produira et le résultat du calcul sera négatif **.

Commentaire

Vous pouvez écrire du code externe (langage C) dans du code Ruby en écrivant require'inline 'sur la première ligne. La description int sur la 6ème ligne définit le type de données de type int pour chacun. Cependant, avec cela, une valeur aberrante avec un affichage négatif apparaît à partir de la 36e réponse dans la séquence Tribonacci.

35e réponse 1831177831 36ème réponse-926906165

Ce phénomène est appelé ** débordement arithmétique **. En langage C, le système de traitement qui devient la valeur minimale LONG_MIN (-2147483648) lorsque la valeur maximale de int, INT_MAX (2147483647), est dépassée de 1. Dans cette implémentation, il semble que le 36e élément a dépassé INT_MAX (2147483647) et a commencé à partir de -2147483648.

Cette fois, nous passerons de int à long pour éviter un dépassement arithmétique. valeur maximale longue: 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)

En passant à long, le 36e 3368061131 sort. À propos, les entiers Ruby sont automatiquement développés en nombre de chiffres, il n'y a donc pas de débordement arithmétique. Donc, si je ne touchais que Ruby, je ne rencontrerais pas de débordement arithmétique. Merci d'avoir rencontré! !!

en conclusion

J'ai beaucoup appris en rencontrant une erreur que je ne rencontre pas dans Ruby après avoir simplement touché le langage C. Actuellement, je n'ai pu introduire que le gem'RubyInline ', mais à l'avenir j'aimerais créer une bibliothèque d'extensions pour le langage C et implémenter un traitement à grande vitesse pour résoudre des problèmes mathématiques intenses.

prime

Si quelqu'un a un problème mathématique intéressant, laissez-le dans les commentaires! !! Le processus de résolution était très éducatif et j'étais accro aux problèmes mathématiques. Basé sur l'esprit de Connecting the dots, je continuerai à faire de mon mieux, croyant que les jours d'immersion brilleront un jour!

Recommended Posts

L'histoire de la rencontre d'un débordement arithmétique qui ne devrait pas être rencontré dans Ruby
Une histoire sur la conversion des codes de caractères de UTF-8 en Shift-jis en Ruby
Une histoire sur le JDK à l'ère de Java 11
Une histoire très utile sur la classe Struct de Ruby
Une histoire sur la création d'un Builder qui hérite du Builder
Une histoire sur une erreur lors de la migration dans docker PHP Laravel
J'ai fait un interpréteur (compilateur?) Avec environ 80 lignes en Ruby.
Comment changer une chaîne dans un tableau en un nombre dans Ruby
Une histoire sur une BeanNotOfRequiredTypeException qui s'est produite après l'application d'AOP au printemps
[Docker] Une histoire sur une erreur dans la composition de docker
Une histoire qu'un débutant Ruby a fait et a publié un LINE BOT qui raconte l'heure du train en 2 mois
Multiplication dans un tableau Ruby
À propos des expressions régulières dans Ruby
L'histoire que Tomcat a souffert d'une erreur de timeout dans Eclipse
Une histoire sur la rédaction d'un calcul de ratio lors d'une session d'étude en interne
Lorsque vous recevez un appel, envoyez un SMS à ce numéro
Créer une ArrayList qui vous permet de lancer et de récupérer les coordonnées d'un plan bidimensionnel