How to convert a number in a string to an integer - ruby

I have an output like "35%" from one command, and I stripped "%". Still, it's stored as a string. Is there a function to convert the string to integer?

You can simply do "35%".to_i which produces 35
For your exact problem:
puts 'true' if 35 == "35".to_i
output is:
true

Let's say your string is "35%". Start reading your string character by character. First your pointer is at '3'. Subtract '0'(ASCII 0) from this and multiply the result by 10. Go to the next character, '5' in this case and again subtract '0' but multiply the result by 1. Now add the 2 results and what you get is integer type 35. So what you are basically doing is subtracting '0' from each character and multiplying it by 10^(its position), until you hit your terminator(% here).

Related

Keep leading zeroes when converting string to integer

For no particular reason, I am trying to add a #reverse method to the Integer class:
class Integer
def reverse
self.to_s.reverse.to_i
end
end
puts 1337.reverse # => 7331
puts 1000.reverse # => 1
This works fine except for numbers ending in a 0, as shown when 1000.reverse returns 1 rather than 0001. Is there any way to keep leading zeroes when converting a string into an integer?
Short answer: no, you cant.
2.1.5 :001 > 0001
=> 1
0001 doesn't make sense at all as Integer. In the Integer world, 0001 is exactly as 1.
Moreover, the number of leading integer is generally irrelevant, unless you need to pad some integer for displaying, but in this case you are probably converting it into another kind of object (e.g a String).
If you want to keep the integer as Fixnum you will not be able to add leading zeros.
The real question is: why do you want/need leading zeros? You didn't provide such information in the question. There are probably better ways to achieve your result (such as wrapping the value into a decorator object if the goal is to properly format a result for display).
Does rjust work for you?
1000.to_s.reverse.to_i.to_s.rjust(1000.to_s.size,'0') #=> "0001"
self.to_s.to_i does convert the integer to a string and this string "0001" to an integer value. Since leading zeros are not required for regular numbers they are dropped. In other words: Keeping leading zeros does not make sense for calculations, so they are dropped. Just ask yourself how the integer 1 would look like if leading zeros would be preserved, since it represents a 32 bit number. If you need the leading zeros, there is no way around a string.
BUT 10 + "0001".to_i returns 11, so you probably need to override the + method of the String class.

how to check whether the string taken through gui is a binary string in matlab?

I am working on a watermarking project that embeds binary values (i.e 1s and 0s) in the image, for which I have to take the input from the user, and check certain conditions such as
1) no empty string
2) no other character or special character
3) no number other than 0 and 1
is entered.
The following code just checks the first condition. Is there any default function in Matlab to check whether entered string is binary
int_state = get(handles.edit1,'String'); %edit1 is the Tag of edit box
if isempty(int_state)`
fprintf('Error: Enter Text first\n');
else
%computation code
end
There is no such standard function, but the check can be easily implemented.
Use this error condition:
isempty(int_state) || any(~ismember(int_state, '01'))
It returns false (no error) if the string is non-empty and composed of '0's and '1's only.
The function ismember returns a boolean array that indicates for every character in int_state whether it is contained in the second argument, '01'. The advantage is that this can be generalized to arbitrary sets of allowed characters.
I think the 2nd and 3rd can be combined together as 1 condition: your input string can only be a combination of 0 and 1? If it is so, then a small trick with findstr can do that:
if length(findstr(input_str, '1')) + length(findstr(input_str, '0')) == length(input_str)
condition_satisfied;
end
tf = isnumeric(A) returns true if A is a numeric array and false otherwise.
A numeric array is any of the numeric types and any subclasses of those types.
isnumeric(A)
ans =
1 (when A is numeric).

Why is "string".to_i = 0 but "9".to_i =9

Hello I was wondering why this was the case and how to_i is defined.
simple question why does
"string".to_i
=> 0?
"9".to_i
=> 9
According to the documentation for to_i, "if there is not a valid a number at the start of str, 0 is returned".
Invoking .to_i on a string will return a number (in base 10) by interpreting valid numbers at the beginning of the string.
"string".to_i returns 0 because .to_i couldn't interpret a valid number from the start of the string. "9".to_i returns 9 because the leading (or in this case, the only) character is "9" and it could be interpreted as a valid number.
This doesn't mean that invoking .to_i on a string that starts with a letter will always return 0 though. For example, "b6".to_i(16) returns 182 because this means you want to interpret "b6" (in base 16, aka hexadecimal) as base 10.
See the documentation here: http://www.ruby-doc.org/core-2.1.0/String.html#method-i-to_i

How can I increase the number of decimal digits when converting BigDecimal to String?

I am facing a problem with BigDecimal.
This code:
x = BigDecimal.new('1.0') / 7
puts x.to_s
outputs:
0.142857142857142857E0
I want to increase the number of digits.
In JAVA, I could do:
BigDecimal n = new BigDecimal("1");
BigDecimal d = new BigDecimal("7");
n = n.divide(d,200, RoundingMode.HALF_UP);
System.out.println(n);
The output is:
0.1428571428571428571428571428571428571428571428571428571428... (200 digits)
I looked at BigDecimal documentation, and tried to set the digits when instantiating the number, then tried to set the limit with the BigDecimal.limit, but I couldn't print more than 18 digits.
What am I missing?
I am running ruby 1.9.3p0 (2011-10-30) [i386-mingw32] on Windows 7 64bits
The div method allows you to specify the digits:
x = BigDecimal.new('1.0').div( 7, 50 )
puts x
With a result of:
0.14285714285714285714285714285714285714285714285714E0
Despite the internal representation of a big decimal, the to_s method is responsible for converting it to a string. I see to_s supports a format string:
Converts the value to a string.
The default format looks like 0.xxxxEnn.
The optional parameter s consists of either an integer; or an optional ‘+’ or ‘ ’, followed by an optional number, followed by an optional ‘E’ or ‘F’.
If there is a ‘+’ at the start of s, positive values are returned with a leading ‘+’.
A space at the start of s returns positive values with a leading space.
If s contains a number, a space is inserted after each group of that many fractional digits.
If s ends with an ‘E’, engineering notation (0.xxxxEnn) is used.
If s ends with an ‘F’, conventional floating point notation is used.
Examples:
BigDecimal.new('-123.45678901234567890').to_s('5F') -> '-123.45678 90123 45678 9'
BigDecimal.new('123.45678901234567890').to_s('+8F') -> '+123.45678901 23456789'
BigDecimal.new('123.45678901234567890').to_s(' F') -> ' 123.4567890123456789'

Converting a hexadecimal number to binary in ruby

I am trying to convert a hex value to a binary value (each bit in the hex string should have an equivalent four bit binary value). I was advised to use this:
num = "0ff" # (say for eg.)
bin = "%0#{num.size*4}b" % num.hex.to_i
This gives me the correct output 000011111111. I am confused with how this works, especially %0#{num.size*4}b. Could someone help me with this?
You can also do:
num = "0ff"
num.hex.to_s(2).rjust(num.size*4, '0')
You may have already figured out, but, num.size*4 is the number of digits that you want to pad the output up to with 0 because one hexadecimal digit is represented by four (log_2 16 = 4) binary digits.
You'll find the answer in the documentation of Kernel#sprintf (as pointed out by the docs for String#%):
http://www.ruby-doc.org/core/classes/Kernel.html#M001433
This is the most straightforward solution I found to convert from hexadecimal to binary:
['DEADBEEF'].pack('H*').unpack('B*').first # => "11011110101011011011111011101111"
And from binary to hexadecimal:
['11011110101011011011111011101111'].pack('B*').unpack1('H*') # => "deadbeef"
Here you can find more information:
Array#pack: https://ruby-doc.org/core-2.7.1/Array.html#method-i-pack
String#unpack1 (similar to unpack): https://ruby-doc.org/core-2.7.1/String.html#method-i-unpack1
This doesn't answer your original question, but I would assume that a lot of people coming here are, instead of looking to turn hexadecimal to actual "0s and 1s" binary output, to decode hexadecimal to a byte string representation (in the spirit of such utilities as hex2bin). As such, here is a good method for doing exactly that:
def hex_to_bin(hex)
# Prepend a '0' for padding if you don't have an even number of chars
hex = '0' << hex unless (hex.length % 2) == 0
hex.scan(/[A-Fa-f0-9]{2}/).inject('') { |encoded, byte| encoded << [byte].pack('H2') }
end
Getting back to hex again is much easier:
def bin_to_hex(bin)
bin.unpack('H*').first
end
Converting the string of hex digits back to binary is just as easy. Take the hex digits two at a time (since each byte can range from 00 to FF), convert the digits to a character, and join them back together.
def hex_to_bin(s) s.scan(/../).map { |x| x.hex.chr }.join end

Resources