# Converting string of bytes to integer

**URL:** https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962
**Category:** General Usage
**Tags:** question
**Created:** [April 10, 2021, 3:04am UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962 "2021-04-10T03:04:12Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![SudhakarKuma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sudhakarkuma/32/23800_2.png) [@SudhakarKuma](https://discourse.julialang.org/u/SudhakarKuma)
#### Post date: [April 10, 2021, 3:04am UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/1 "2021-04-10T03:04:12Z")

</div>

I am working on interfacing Arduino with Julia. There is a particular experiment of reading the values from a sensor connected to Arduino. For this, I have written a function in **Julia 1.6.0**. This function reads the values coming from the serial port. These values are strings like **@\x02**. So, I need to convert this string (let us say, **s** ) into an integer value. For this, I am using the **parse** function, as given below:

```julia
num = parse(Int, s) # Convert String to integer
println(num) 

```

While executing this, I get an error as shown below:

> LoadError: ArgumentError: invalid base 10 digit ‘@’ in “@\x02”

While finding its solution on the Internet, I came across the built-in functions in Python, as given on [Free Bootcamp Prep | Flatiron School](https://learn.co/lessons/bytes-to-int-jsong). By following the functions given on this website, I could get the desired value from the string in Python, as shown below:

```julia
>>> lit = b'@\x02'
>>> n = int.from_bytes(lit, 'little')
>>> n
576

```

Could you please help me with implementing the same in **Julia**? Is there any built-in function in Julia that can help in converting from string (of bytes) to integer?

Thanking you in anticipation,

Regards,  
Sudhakar

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [April 10, 2021, 8:38am UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/2 "2021-04-10T08:38:26Z")

</div>

Strings in both Python (`str`) and Julia (`String`) encode text in Unicode. It’s not the same as the byte sequences you’re working with. The `b'@\x02'` in your Python example makes a `bytes` object, not a string. Julia also has [bytes literals (docs here)](https://docs.julialang.org/en/v1/manual/strings/#man-byte-array-literals).  
I did a bit of reading and I can get `576` by going through an `IOBuffer`:

```julia
lit = b"@\x02"
iolit = IOBuffer(lit)
n = read(iolit, Int16) # 576
# cannot read anymore from iolit, already at end
close(iolit)

```

I don’t think making and closing an `IOBuffer` for every couple of bytes like this is the right answer, but at least this shows it’s feasible. I also don’t know how to take the byte order into account (the argument `'little'` in the Python example).

---

<div class="post-metadata">

### Author: ![SudhakarKuma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sudhakarkuma/32/23800_2.png) [@SudhakarKuma](https://discourse.julialang.org/u/SudhakarKuma)
#### Post date: [April 10, 2021, 10:17am UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/3 "2021-04-10T10:17:07Z")

</div>

Thanks, @Benny, for your response. I have been able to get the value now. However, I have a function that receives the strings and then returns the equivalent integer value. This function is as given below.

```julia
function analogRead(file_des::SerialPorts.SerialPort , pin_no::Int64)
  str = "A"*string(Char(48+pin_no)) #"An" for analog value on pin n
  write(file_des,str)
  sleep(0.1) # Delay next step by 100 milliseconds
  n = bytesavailable(file_des) # Get number of bytes in input buffer
  s = read(file_des, n) # Read n bytes from SerialPort
  #######################################
  # Need to add the code to get the integer num from s 
  #######################################
 return num # Return the equivalent integer
end

```

In the above function, when I get the string in **s** , I need to make it a byte literal and then convert it into an integer value. In other words, I need to add a command in this function, which takes **s** (assuming that **s = “@\x02”** ) and returns the byte literal of this **s** ( **b"@\x02"** ). This means I need to know how I can add **b** in this string. I have tried the **star(\*)** operator to concatenate **b** (referring to byte) and the string **s**. However, it creates another string **“b@\x02”** , whereas we need **b"@\x02"**.

Could you please help me with how to obtain a byte literal from the string?

Thanking you in anticipation,

Regards,  
Sudhakar

---

<div class="post-metadata">

### Author: ![SudhakarKuma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sudhakarkuma/32/23800_2.png) [@SudhakarKuma](https://discourse.julialang.org/u/SudhakarKuma)
#### Post date: [April 10, 2021, 2:18pm UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/4 "2021-04-10T14:18:24Z")

</div>

I got this working by rewriting the function as given below:

```julia
function analogRead(file_des::SerialPorts.SerialPort , pin_no::Int64)
  str = "A"*string(Char(48+pin_no)) #"An" for analog value on pin n
  write(file_des,str)
  sleep(0.1) # Delay next step by 100 milliseconds
  n = bytesavailable(file_des) # Get number of bytes in input buffer
  s = read(file_des, n) # Read n bytes from SerialPort
  iolit = IOBuffer(s) 
  num = read(iolit, Int16)
  # println(sizeof(num))
  # println(num[1])
  # @printf("value = %d", Int(num))
  close(iolit)
  
  # typeof(s) 
  # k = parse(Int,s) # Convert String to integer
  return num # Return the integer
end

```

Thank you, @Benny, for your response.

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [April 10, 2021, 2:25pm UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/5 "2021-04-10T14:25:47Z")

</div>

Using [`reinterpret`](https://docs.julialang.org/en/v1/base/arrays/#Base.reinterpret) should be faster than going through `IOBuffer`s:

```julia
# Generate random `Int16`s
julia> nums = rand(Int16, 2)
2-element Vector{Int16}:
  10792
 -18596

# Convert to bytes, this is your actual input
julia> bytes = collect(reinterpret(UInt8, nums))
4-element Vector{UInt8}:
 0x28
 0x2a
 0x5c
 0xb7

# Reintepret as `Int16`, you'll get back the same numbers we generated above
julia> reinterpret(Int16, bytes)
2-element reinterpret(Int16, ::Vector{UInt8}):
  10792
 -18596

```

Or, if you want to start from a byte string:

```julia
# your original example
julia> reinterpret(Int16, b"@\x02")
1-element reinterpret(Int16, ::Base.CodeUnits{UInt8, String}):
 576

# Generate a new random byte string
julia> input = String(rand(UInt8, 8))
"\xb2\Ub2aab\xca3 "

# Reinterpret as `Int16`
julia> reinterpret(Int16, codeunits(input))
4-element reinterpret(Int16, ::Base.CodeUnits{UInt8, String}):
  -3406
 -21838
 -13653
   8243

```

Benchmarks:

```julia
julia> using BenchmarkTools

julia> f(s) = reinterpret(Int16, s)
f (generic function with 1 method)

julia> function g(s)
           io = IOBuffer(s)
           n = read(io, Int16)
           close(io)
           return n
       end
g (generic function with 1 method)

julia> @btime f($(b"@\x02"))
  3.542 ns (0 allocations: 0 bytes)
1-element reinterpret(Int16, ::Base.CodeUnits{UInt8, String}):
 576

julia> @btime g($(b"@\x02"))
  10.278 ns (1 allocation: 64 bytes)
576

```

Note that `reinterpret` is completely non-allocating and you don’t need to read numbers one-by-one

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [April 10, 2021, 11:10pm UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/6 "2021-04-10T23:10:36Z")

</div>

1. I suggest removing the Solution mark from my earlier response because, as I pointed out (and demonstrated by @giordano) , making and closing `IOBuffer`s like that every time you read bytes from `SerialPort` wastes memory and hurts performance. It’s better if you leave this question open so that people who have worked on similar projects know to give you better answers.
2. @giordano answer actually looks like a great replacement for Python’s `int.from_bytes`, can even be used to switch between other types.
3. It actually looks like `SerialPort` is already some sort of IO object because it has `read` and `write`, so making `IOBuffer` seems redundant.
4. Literals syntax like `b""` is just a convenient way to write a type of object in code, it’s not a `b` concatenated to a `String` object. It’s like how `Int8[1,2,3]` makes an `Array{Int8, 1}`; it’s not an `Int8` concatenated to `[1,2,3]`.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [April 11, 2021, 12:18am UTC](https://discourse.julialang.org/t/converting-string-of-bytes-to-integer/58962/7 "2021-04-11T00:18:04Z")

</div>

> [@SudhakarKuma](#):
>
> ```julia
> s = read(file_des, n) # Read n bytes from SerialPort
> iolit = IOBuffer(s) 
> num = read(iolit, Int16)
> 
> ```

Why not just `num = read(file_des, Int16)`?
