`
simohayha
  • 浏览: 1403585 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

ruby way之数值计算之二

    博客分类:
  • ruby
阅读更多
1 处理复数

标准库complex 能使我们处理复数。一个复数的创建能使用Complex来构造:
require 'complex'

puts Complex(1,2)    # 3+5i


方法im能够转换一个数字为虚数:
puts a = 3.im       # 3i
puts b = 5 - 2.im   # 5-2i


如果你想表示极坐标的话,可以使用polar方法:

puts z = Complex.polar(5,Math::PI/2.0)  #第一个参数是半径,第二个参数是角度


Complex还提供了I这个常量,他就表示复数中的i:
puts z1 = Complex(3,5)
puts z2 = 3 + 5*Complex::I   


当complex库被load之后,Numeric类及其子类都会被改变,因为这个时候他们会认为,所有的数都是复数:

puts y = Math.sqrt(-1) #1.oi


2使用mathn

对于对数学计算要求很高的程序,我们可以选择使用mathn标准库。当你require 他的同时,complex, rational,和matrix库 也会被require进来。因为它本身就require了其他的几个库。

mathn库尝试着给出你更合适的结果:
require 'mathn'
puts Math.sqrt(Rational(9,16))    #3/4

puts 1/2                          #1/2
puts Matrix.identity(3)/3                #Matrix[[1/3, 0, 0], [0, 1/3, 0], [0, 0, 1/3]]
puts Math.sqrt(64/25)              #8/5

puts Rational(1,10).inspect            #1/10

mathn 库还给Rational加入了**和power2 方法,他改变了Math.sqrt的行为,因此给他加入了一个Math.rsqrt方法.

3 计算因式分解,最大公约数和最小公倍数

mathn库提供了gcd方法来计算两个数的最大公约数:

puts n = 36.gcd(120)    # 12
puts k = 237.gcd(79)    # 79


prime_division方法提供一个因式分解:
puts 126.prime_division.to_s  #[[2, 1], [3, 2], [7, 1]] 表示2**1 * 3**2 * 7**1 


from_prime_division方法则可以将一个分解了的因式重新组合起来:

factors = [[2,1],[3,2],[7,1]]
puts num = Integer.from_prime_division(factors)


lcm则可以计算两个数的最小公倍数:

puts 10.lcm(5) 


4处理质数

mathn库提供了一个Prime类来处理质数,我们可以使用each来提取指数:

list = []
gen = Prime.new
gen.each do |prime|
  list << prime
  break if list.size == 100
end

puts list.to_s #打印出前100个质数

#和上面的结果一样
list = []
gen = Prime.new
100.times { list << gen.succ }
puts list.to_s


下面的代码可以使我们判断一个数是否为质数:

require 'mathn'

class Integer
  def prime?
    max = Math.sqrt(self).ceil  
    max -= 1 if max % 2 == 0
    pgen = Prime.new
    pgen.each do |factor|
      return false if self % factor == 0
      return true if factor > max
    end
  end
end

31.prime?           # true
237.prime?          # false
1500450271.prime?   # true


5 隐式和显式的数值转换

这节就是解释一下to_i和to_int之间的差别(也包括to_f和to_flt).其实他们之间的差别就h和to_s和to_str之间的差别是一样,也就是说to_int是一个隐式的转换:

class MyClass
  def to_i
    3
  end

  def to_int
    5
  end
end
a=MyClass.new
puts Array.new(a).to_s #[nil, nil, nil, nil, nil]


6Coercing Numeric Values

Coercion也就是一种隐式的转换,当一个方法被传进去了他所不能理解的参数的时候,它会尝试着强迫接收者和参数变为能够相处的类型(比如说你将一个整数和一个浮点数相加它会使用coerce方法将整数和浮点数处理为可以相容的格式(比如都转成整数),然我们这边先定义一个自己的coerce方法,coerce 将会返回一个含有两个数字的数组,它把接收者和参数转换成可以相容的类型.
def coerce(other)
  if other.kind_of?(Float)
    return other, self.to_f
  elsif other.kind_of?(Integer)
    return other, self.to_i
  else
    super
  end
end
class String
  def coerce(n)
    if self['.']
      [n, Float(self)]
    else
      [n, Integer(self)]
    end
  end

end
puts x = 1 + "23"        # 24
puts y = 23 * "1.23"     # 28.29


如果你想创建一些进行算术计算的类时(比如你想要进行罗马数字的计算),我们建议你实现自己的coerce方法。

7 对数字进行按位运算

经常我们想要处理Fixnum作为一个二进制数字.数值类型能够被表示为2进制,8进制和16进制,因此我们能够使用&, |, ^, 和~这些位操作符,来操作位:

x = 0377           # Octal  (decimal 255)
y = 0b00100110     # Binary (decimal  38)
z = 0xBEEF         # Hex    (decimal 48879)

puts a = x | z          # 48895 (bitwise OR)
puts b = x & z          #   239 (bitwise AND)
puts c = x ^ z          # 48656 (bitwise XOR)
puts d = ~ y            #   -39 (negation or 1's complement)

我们可以使用size方法来返回机器所表示的字节数:

puts 1.size #4


ruby中的移位操作都是逻辑移位

x = 8
y = -8

puts a = x >> 2         # 2
puts b = y >> 2         # -2
puts c = x << 2         # 32
puts d = y << 2         # -32


[]能够将一个数值当作一个位数组来对待:

x = 5              # Same as 0b0101
puts a = x[0]           # 1
puts b = x[1]           # 0
puts c = x[2]           # 1
puts d = x[3]           # 0


我们虽然不能直接使用[]=来改变数值的某一位的值,可是我们能够使用移位+逻辑操作来实现:

# We can't do x[3] = 1
# but we can do:
puts x |= (1<<3)
# We can't do x[4] = 0
# but we can do:
puts x &= ~(1<<4)


8 执行进制转换

我们能够使用to_s来转换一个数值的进制,默认不带参数是10进制:
puts 237.to_s(2)            # "11101101"
puts 237.to_s(5)            # "1422"
puts 237.to_s(8)            # "355"
puts 237.to_s               # "237"
puts 237.to_s(16)           # "ed"
puts 237.to_s(30)           # "7r"


我们还能使用%来操作:

puts hex = "%x" % 1234      # "4d2"
puts oct = "%o" % 1234      # "2322"
puts bin = "%b" % 1234      # "10011010010"


当然sprintf也可以进行转换:

str = sprintf(str,"Nietzsche is %x\n",57005)
# str is now: "Nietzsche is dead\n"


9 执行立方根,4次方根,等等

如果我们想得到高次方的根,我们能够使用log的变化就能得到(高数里面的):

x = 531441
puts cuberoot = Math.exp(Math.log(x)/3.0)     # 81.0
puts fourthroot = Math.exp(Math.log(x)/4.0)   # 27.0


当然我们还能使用更简单的方法:

include Math
y = 4096
puts cuberoot = y**(1.0/3.0)      # 16.0
puts fourthroot = y**(1.0/4.0)    # 8.0
puts fourthroot = sqrt(sqrt(y))   # 8.0 (same thing)
puts twelfthroot = y**(1.0/12.0)  # 2.0


10确定机器的大小端

觉得用ruby的话,好麻烦,我就把程序给出来吧,我们这里还有一个自己写的(用c写的),其时用c的话也有好多种方法:

def endianness
  num=0x12345678
  little = "78563412"
  big    = "12345678"
  native = [num].pack('l')
  netunpack = native.unpack('N')[0]
  str = "%8x" % netunpack
  case str
    when little
      "LITTLE"
    when big
      "BIG"
    else
      "OTHER"
  end
end

puts endianness   # In this case, prints "LITTLE"


int is_little_endian()
{
	int a=1;
	return *(char *)&a;
}


或者说用一个union来写,更漂亮...



分享到:
评论

相关推荐

    The Ruby Way(第2版)

    The Ruby Way(第2版) &lt;br&gt;The Ruby Way assumes that the reader is already familiar with the subject matter. Using many code samples it focuses on "how-to use Ruby" for specific applications, either ...

    The Ruby Way--3rd Edition--2015-英文版

    The Ruby Way 第三版(英文版),全书22章,书中包含600多个按主题分类的示例。每个示例都回答了“如何使用Ruby来完成”的问题。 ——Ruby on Rails之父David Heinemeier Hansson倾力推荐!

    THE RUBY WAY(中文版)(第二版)pdf

    《The Ruby Way 第二版》...“《The Ruby Way (第2版)中文版》在阐述元编程(metaprogramming)等方面尤其出类拔萃,而元编程是Ruby最引人注目的方面之一。” ——Ruby on Rails之父David Heinemeier Hansson倾力推荐!

    the ruby way 2ed

    《The Ruby Way 2nd Edition》是一本深入探讨Ruby编程语言的经典著作,旨在帮助读者全面理解和掌握Ruby的精髓。这本书的第二版在2006年出版,由Addison-Wesley出版,作者通过深入浅出的方式,揭示了Ruby语言的强大...

    ruby学习资源(Programming Ruby, Learning Ruby, The Ruby Way)

    内含以下4个文档: 1、Addison.Wesley.The.Ruby.Way.2nd.Edition.Oct.2006.chm 2、O'Reilly.Learning.Ruby.May.2007.chm 3、Programming Ruby 2e.pdf 4、ruby中文文档.chm

    the-ruby-way

    the ruby way the ruby way

    Addison Wesley The Ruby Way 2Nd Edition Oct 2006.pdf(英文版)

    ### Addison Wesley《The Ruby Way》第二版(2006年10月) #### 书籍概览 《The Ruby Way》是由Hal Fulton编写的关于Ruby编程语言的经典著作,该书的第二版出版于2006年10月,由Addison Wesley Professional出版社...

    11.5 时间日期the ruby way.rar

    "11.5 时间日期the ruby way"这个主题深入探讨了Ruby中处理时间日期的最佳实践和常见用法。让我们逐一了解这些知识点。 首先,`Time.now`是Ruby中获取当前时间的标准方法。它返回一个`Time`对象,表示自1970年1月1...

    the ruby way

    《The Ruby Way》是一本备受推崇的Ruby编程教程,它以独特的方式深入浅出地介绍了Ruby语言。这本书的核心理念是“如何解决问题”,作者通过实际的编程示例和问题解决策略,帮助读者理解Ruby的强大功能和优雅语法。 ...

    Ruby-Way.rar_About Language

    《Ruby Way》是由Hal Fulton编写的关于Ruby编程语言的一本著作。这本书深入浅出地探讨了Ruby语言的各种特性,旨在帮助读者理解并掌握这门强大的动态脚本语言。Ruby以其简洁、优雅的语法和强大的元编程能力而备受赞誉...

    Ruby.Programming_向Ruby之父学程序设计(第2版)

    《Ruby Programming:向Ruby之父学程序设计(第2版)》是为了让完全没有程序设计经验的读者也能灵活地使用Ruby,因此书中详细地说明了各种知识。从程序所需要的变量、常数、方法、类、控制结构等语法的说明,到类的主要...

    Addison.Wesley.The.Ruby.Way.2nd.Edition.Oct.2006.chm

    《The Ruby Way》第二版是Addison-Wesley出版社在2006年推出的一本深入浅出的Ruby编程语言教程。这本书专为初学者设计,旨在帮助读者快速掌握Ruby语言的基础和高级特性,从而轻松入门Ruby编程。Ruby是一种动态、开放...

    ruby2ruby.zip

    ruby2ruby 提供一些用来根据 RubyParser 兼容的 Sexps 轻松生成纯 Ruby 代码的方法。可在 Ruby 中轻松实现动态语言处理。 标签:ruby2ruby

    src-oepkgs/ruby-ruby2ruby

    src-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2rubysrc-oepkgs/ruby-ruby2...

    The Ruby Way(处理文件和目录)

    计算机的主要功能之一就是处理数据,这不仅包括内部计算,还包括输入输出(I/O)操作,即与外部世界的交互。Ruby作为一种现代的编程语言,为用户提供了一套强大且灵活的方式来处理文件和目录。下面将详细介绍Ruby中...

Global site tag (gtag.js) - Google Analytics