Pipe Operator | and 3 dots and 2 greater than

like this! (using your original function)

+ Integer {
	decToBinary { |div=2|
		var result;
		var inner = { arg dec;
			var quotient;
			if (dec % div > 0, {
				result = result.add(1);
			}, {
				result = result.add(0);
			});
			quotient = (dec / div).floor.asInteger;
			if (quotient > 0, {
				inner.value(quotient, div);
			});
			result.reverse.join;
		};
		^inner.(this)
	}

}

note div is defined in the outer scope no need to define within.

also you can substitute

result = result.add(dec % div);

for your first if statement if you want to save a few lines!

Thank you very much, it makes sense.

Hmm, well:

  • decToBinary:

    1. The number isn’t decimal to begin with. It’s already binary. You’re not “converting from decimal,” so the name is a bit misleading.
    2. “ToBinary” but there’s a div argument for the numeric base – so it isn’t necessarily converting to binary either – so it’s really more of a “convert to a string using a given base” method (but both “dec” and “binary” are not accurate).
  • “also you can substitute result = result.add(dec % div); for your first if statement if you want to save a few lines!” – It isn’t only to save a few lines. The method allows div > 2 but the if statement means that the result will be valid only for div == 2. (If div == 3, then this % div may be 0, 1, or 2 – but the if breaks the result for 2.)

  • The method doesn’t handle negative numbers.

  • EDIT: Also, throw an error if div < 2. Negative or 0 div are nonsense. div == 1 → infinite recursion (very important to halt!).

  • EDIT: asDigit the modulo, to handle base > 10.

  • You can do the recursion without reversing the result, by prepending instead of adding.

I guess I would:

+ Integer {
	prAsStringBase { |base = 10|
		if(base < 2) { Error("invalid base " ++ base).throw };
		^ if(this < 0) {
			"-" ++ this.neg.asStringBase(base)
		} {
			if(this == 0) {
				""
			} {
				(this div: base).prAsStringBase(base) ++ (this mod: base).asDigit
			}
		}
	}

	asStringBase { |base = 10|
		var str = this.abs.prAsStringBase(base);
		^ if(str == "") { "0" } {
			if(this < 0) {
				"-" ++ base.asString ++ "r" ++ str
			} {
				base.asString ++ "r" ++ str
			}
		}
	}
}

hjh

Many good lessons in your example James!

I think OP meant “I type a decimal representation followed by a method call and I want to see a binary representation (asString) returned” so I think the method name is ok!

Not sure why you say an Integer “is” binary - an existential question praps

(7r32653).decToBinary(10) – Better rename the method to septToDecimal then :wink:

Yes, that’s a bit perverse – but, there’s no guarantee that the input integer was written using base 10 characters (could be any supported input base – e.g., more commonly, 0x201D is the same as 7r32653 – nobody’s seriously going to write numbers in base 7, but there are a lot of cases for writing integers in hexadecimal), and there’s no guarantee that it’s being converted into a string of binary digits.

Because the memory storage is, objectively, binary. If you have x = 200, somewhere in memory will be the sequence of bits 00000000000000000000000011001000. You may have written it as 200 but the compiler has already converted it into 32 bits before the interpreter even starts to run the code. At the point of reaching decToBinary, “decimal” left the building long ago.

hjh

Thank you both of you

I don’t think the representation somewhere in the machine determines the essence of the thing being represented! Integers post in decimal notation as a default - I suppose the “Integer” is platonic and independant of the notation used to represent. That said maybe the interface is a more useful determinant of category here… We can represent imaginary numbers despite not having imaginary bits. (pace quantum computing ppl)

Then you’ve demonstrated why the method name should not assume a specific base :wink:

hjh