রুবি সর্বাধিক পূর্ণসংখ্যা


89

আমার রুবিতে একটি সিস্টেম সর্বোচ্চ সংখ্যার নির্ধারণ করতে সক্ষম হতে হবে need কেউ জানেন কীভাবে, বা সম্ভব হলে?

উত্তর:


50

রুবি যখন ওভারফ্লো হয়ে যায় তখন পূর্ণসংখ্যাটিকে একটি বড় পূর্ণসংখ্যার শ্রেণিতে স্বয়ংক্রিয়ভাবে রূপান্তরিত করে, সুতরাং তারা কতটা বড় হতে পারে তার (সীমাবদ্ধভাবে) কোনও সীমা নেই।

আপনি যদি মেশিনের আকার, যেমন -৪- বা ৩২-বিটের সন্ধান করেন তবে আমি এই কৌশলটি রুবি-ফোরাম ডটকম এ পেয়েছি :

machine_bytes = ['foo'].pack('p').size
machine_bits = machine_bytes * 8
machine_max_signed = 2**(machine_bits-1) - 1
machine_max_unsigned = 2**machine_bits - 1

আপনি যদি ফিকনাম অবজেক্টের আকার (একক মেশিনের শব্দের মধ্যে যথেষ্ট ছোট ছোট পূর্ণসংখ্যার) জন্য সন্ধান করছেন তবে আপনি 0.sizeবাইটের সংখ্যা পেতে কল করতে পারেন। আমি অনুমান করব এটি 32-বিট তৈরিতে 4 হওয়া উচিত, তবে আমি এখনই এটি পরীক্ষা করতে পারি না। এছাড়াও, বৃহত্তম ফিক্সনাম দৃশ্যত 2**30 - 1(বা 2**62 - 1), কারণ একটি বিট এটি কোনও অবজেক্টের রেফারেন্সের পরিবর্তে পূর্ণসংখ্যা হিসাবে চিহ্নিত করতে ব্যবহৃত হয়।


4
খুব নিশ্চিত যে আপনি 2 ** চান (মেশিন_ আকার * 8) -1; 2 ** 4-1 = 15 যা খুব বড় কিছু নয়।
সেবজায়ার

উফফ, আমার ধারণা আমি বিটের পরিবর্তে বাইট সম্পর্কে খুব বেশি চিন্তাভাবনা শুরু করেছি।
ম্যাথু ক্রামলে

10
সতর্কতা: কোডটি অকেজো। সম্পাদনাটি পড়ুন, কোডটি উপেক্ষা করুন। এটি রুবির সর্বাধিক কিছুই খুঁজে পায় না। এটি কোডের জন্য এটি খুঁজে পেয়েছে যা ট্যাগড পয়েন্টার ব্যবহার করে না।
সিজে

এখন (2018-01-21) এটি উইন্ডোজের 64 বিবি রুবিতেও 32 বীট রয়েছে (সাইগউইন অন্যদিকে যথাযথ 64 বিট রয়েছে)
গ্রেওয়াল্ফ

81
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
FIXNUM_MIN = -(2**(0.size * 8 -2))

4
আপনি কেন সাইনটির জন্য 1 টির পরিবর্তে 2 বিট বিয়োগ করেছেন? আমি এটি পরীক্ষা করেছি এবং এটি সঠিক বলে মনে হচ্ছে, তবে কেন রুবি চিহ্নটির জন্য 2 বিট ব্যবহার করে?
ম্যাথিয়াস

29
@ মাথিয়াস একটি অতিরিক্ত বিট মানটিকে পূর্ণসংখ্যা হিসাবে চিহ্নিত করতে ব্যবহৃত হয় (কোনও বস্তুর পয়েন্টারের বিপরীতে)।
ম্যাথু ক্রামলে

4
এটি অন্তত জেআরবির পক্ষে সত্য নয়। জেআরবিতে Fixnumসর্বদা B৪ বিট থাকে ( AR৩ বা 31 টি বিএআরভি-র মতো নয়) মেশিন শব্দের আকার নির্বিশেষে, এবং কোনও ট্যাগ বিট নেই।
জার্গ ডব্লু মিটাগ

13

বন্ধুত্বপূর্ণ ম্যানুয়াল পড়া? কে এটা করতে চাই?

start = Time.now
largest_known_fixnum = 1
smallest_known_bignum = nil

until smallest_known_bignum == largest_known_fixnum + 1
  if smallest_known_bignum.nil?
    next_number_to_try = largest_known_fixnum * 1000
  else
    next_number_to_try = (smallest_known_bignum + largest_known_fixnum) / 2 # Geometric mean would be more efficient, but more risky
  end

  if next_number_to_try <= largest_known_fixnum ||
       smallest_known_bignum && next_number_to_try >= smallest_known_bignum
    raise "Can't happen case" 
  end

  case next_number_to_try
    when Bignum then smallest_known_bignum = next_number_to_try
    when Fixnum then largest_known_fixnum = next_number_to_try
    else raise "Can't happen case"
  end
end

finish = Time.now
puts "The largest fixnum is #{largest_known_fixnum}"
puts "The smallest bignum is #{smallest_known_bignum}"
puts "Calculation took #{finish - start} seconds"

এটিই কেবল একমাত্র উত্তর বলে মনে হয়েছে যা ফিক্সনাম থেকে বিগনামে রূপান্তরিত হওয়ার সময় সংখ্যার প্রত্যাবর্তন করে, যা আমার কাছে, এটি রুবির বৃহত্তম ফিক্সনাম।
টিন ম্যান

11

রুবিতে ফিক্সনুমস স্বয়ংক্রিয়ভাবে বিগনুমে রূপান্তরিত হয়।

সর্বোচ্চ সম্ভাব্য ফিক্সনাম সন্ধানের জন্য আপনি এরকম কিছু করতে পারেন:

class Fixnum
 N_BYTES = [42].pack('i').size
 N_BITS = N_BYTES * 8
 MAX = 2 ** (N_BITS - 2) - 1
 MIN = -MAX - 1
end
p(Fixnum::MAX)

নির্লজ্জভাবে একটি রুবি-টক আলোচনা থেকে ছিড়ে । আরও বিশদ জন্য সেখানে দেখুন।


4
আপনি যদি puts (Fixnum::MAX + 1).classএটি করেন তবে Bignumএটির মতো ফিরে আসে না । আপনি যদি এটি পরিবর্তন 8করতে 16হবে।
টিন ম্যান

1

রুগি ২.৪-এর পরে সর্বাধিক নেই কারণ বিগনাম এবং ফিকনাম পূর্ণসংখ্যায় একীভূত হয়েছিল। দেখতে বৈশিষ্ট্য # 12005

> (2 << 1000).is_a? Fixnum
(irb):322: warning: constant ::Fixnum is deprecated
=> true

> 1.is_a? Bignum
(irb):314: warning: constant ::Bignum is deprecated
=> true

> (2 << 1000).class
=> Integer

কোনও ওভারফ্লো হবে না, যা ঘটবে তা হ'ল স্মৃতিশক্তি।


0

যেমন @ জার্গ ডব্লু মিটাগ নির্দেশ করেছেন: জুরবীতে, স্থির নম্বরের আকার সর্বদা 8 বাইট দীর্ঘ হয়। এই কোড স্নিপেট সত্য দেখায়:

fmax = ->{
  if RUBY_PLATFORM == 'java'
    2**63 - 1
  else
    2**(0.size * 8 - 2) - 1
  end
}.call

p fmax.class     # Fixnum

fmax = fmax + 1  

p fmax.class     #Bignum
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.