2012-03-22 2 views
2

설명서를보고 C 소스를 살펴 보았습니다. 왜 그들이 허용 된 기수를 2..36으로 제한했는지 알 수 없습니다. 아무도 몰라?Ruby의 FixNum # to_s 메소드가 2에서 36까지의 radix만을 허용하는 이유는 무엇입니까?

+1

@muistooshort 자료 (1) 지금까지 집계 목록을 한 존재? 또는 테스트 주자 중 일부가 성공적인 테스트를 위해 생성 한 점을 계산합니까? 그 점에 관해서는, 아마도 기본'1/2'과 훨씬 더 미친 것들 (기본'phi' 누군가?)이있을 것입니다. – delnan

답변

6

다른 사람들이 지적했듯이 기수는 < 2입니다. 렌더링하기가 번거 롭습니다. [ '0'.. '9'] + [ 'a'.. 'z']보다 큰 기수에 사용할 문자가 무엇인지에 대한 일반적인 합의가 없기 때문에 표준 방법은 그 한계를 벗어난 기수를 지원하지 않습니다 .

사용자 정의 기수 표현을 정말로 원하면 숫자에 사용할 기호의 알파벳을 정의해야합니다. 여기에 당신에게 능력을 줄 작은 모듈이 있습니다.

module CustomRadix 
    # generate string representation of integer, using digits from custom alphabet 
    # [val] a value which can be cast to integer 
    # [digits] a string or array of strings representing the custom digits 
    def self.custom_radix val, digits 

    digits = digits.to_a unless digits.respond_to? :[] 
    radix = digits.length 
    raise ArgumentError, "radix must have at least two digits" if radix < 2 

    i = val.to_i 
    out = [] 
    begin 
     rem = i % radix 
     i /= radix 
     out << digits[rem..rem] 
    end until i == 0 

    out.reverse.join 
    end 

    # can be used as mixin, eg class Integer; include CustomRadix; end 
    # 32.custom_radix('abcd') => "caa" (200 base 4) equiv to 32.to_s(4).tr('0123','abcd') 
    def custom_radix digits 
    CustomRadix.custom_radix self, digits 
    end 
end 

사용 예제 :

$ irb 
>> require '~/custom_radix' 
=> true 
>> CustomRadix.custom_radix(12345,'0'..'9') 
=> "12345" 
>> CustomRadix.custom_radix(12345,'.-') 
=> "--......---..-" 
>> funny_hex_digits = ('0'..'9').to_a + ('u'..'z').to_a 
=> ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "u", "v", "w", "x", "y", "z"] 
>> CustomRadix.custom_radix(255, funny_hex_digits) 
=> "zz" 
>> class Integer; include CustomRadix; end 
=> Integer 
>> (2**63).custom_radix(funny_hex_digits) 
=> "8000000000000000" 
>> (2**64+2**63+2**62).custom_radix(funny_hex_digits) 
=> "1w000000000000000" 
>> base64_digits = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a << '+' << '/' 
=> ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"] 
>> 123456.custom_radix(base64_digits) 
=> "eJA" 
+0

나는 36과 64 사이의 기수에 대한 규정이 없기 때문에 기수 제한이 2..36 인 이유가 확실합니다. 우수 모듈 및 예제 사용법에 대한 답변 고맙습니다! –

+1

어떻게 "되돌아 와서" "eJA"를'123456'으로 되돌릴 수 있습니까? – Zac

+1

@zac 맞춤 알파벳이있는 atoi입니다. 각 문자에 대해 누산기를 기준 (알파벳 크기)으로 곱하고, 문자를 숫자로 변환하고 누적기를 추가합니다. – dbenhur

2

나는 루비에 대해 아무것도 모른다. 그러나 나는 10 진수와 26 개의 알파 자릿수가 있다는 것을 알고있다. 그게 36이야.

+0

분명히 그럴 수도 있지만 대소 문자를 구별하면 46 자의 영숫자 문자가 있습니다. 실제로 46 개의 문자 세트 중 무작위로 31 개의 문자열을 생성하기를 원했고'31xinject ('') {| i | i << rand (46) .to_s (46)}'가 작동하지 않습니다. –

+1

@sidewaysmilk 그러나 16 진수는 거의 보편적으로 대소 문자를 구별하지 않으며, 높은 기본에 대한 변경은 끔직하게 일치하지 않습니다. – delnan

+0

대신에 base-64 인코딩을 사용하는 것이 좋습니다. – BlueMonkMN

1

어떻게베이스 1에 숫자를 렌더링하겠습니까? 37 번 기지에서 어떻게 숫자를 렌더링하겠습니까? 기수 300?

16 진수는 0..9와 A..F를 사용하는 것이 일반적입니다. 더 높은 기지에 알파벳을 계속 사용하는 것은 직관적이지만 36 점만받습니다. (더 많은 것을 본 적이없는 - 내가 본 적이없는 경우) 상위 기지의 용도는 거의 없으므로 그 이상의 것을위한 협약은 없습니다. 어쩌면 완전히 다른 짐승 인 기지 64를 제외하고, 하나의 기지에만 국한되고 몹시 오래되지는 않았습니다. 또한, gazillion 호환되지 않는 변종, 내 포인트를 강화.

기본 1의 경우 : 단항 계산이 있지만 컴퓨팅에서 덜 유용하고 매우 유용하지는 않으며 매우 쉽게 에뮬레이션 할 수 있습니다 (동일한 문자의 concat n 번). 게다가, 사람들은 아마도 그 캐릭터가 무엇에 있어야하는지에 대해 크게 다른 의견을 가지고있을 것입니다.

관련 문제