Invalid number (error token is "16##0x00a002") - shell

I want to convert a hexadecimal value to decimal value, perform some arithmetic operation and convert it back to hexadecimal.
In an attempt to do so, I am facing the following error,
"myshell.sh: line 77: 16##0x00a002: invalid number (error token is
"16##0x00a002")
The related line of code is:
SUBVER3_1=$((16##$SUBVER3_1))
Can someone let me know:
What this error is and how can i fix it?
How to perform arithmetic operations on hexadecimal numbers in shell?

The 0x prefix is not valid for base 16 notation. Strip it before converting. Also, if you are using Bash, the syntax for base conversion uses a single # after the base.
SUBVER3_1=$((16#${SUBVER3_1#0x}))
This uses the traditional POSIX ${variable#prefix} notation to strip off a prefix. The # in that is unrelated to the base#string notation.
The shell supports basic integer arithmetic. The arithmetic operations are independent of the base you are using; simple addition etc like $((255+255)) can use base-16 notation just as well $((16#FF+16#FF)) but keep in mind that division with only integers is of rather limited usefulness. If you want results in hex, printf can do that:
printf "%04x\n" $((16#ff + 16#ff))

The issue is now resolved,
I used print statement to fix this issue instead of the above statement
SUBVER3_1=$(printf "%x" $SUBVER3_1) # Converting from decimal to hexadecimal
This served the purpose

Related

How to separate variables without spaces

My question is similar to this one, but not really.
The issue is that I have variables in my script that will echo/printf control characters directly next to the previous. Unfortunately I have to put spaces between the variables or everything gets misinterpreted, but that's not going to work either, as I can't have spaces between them.
str="25 cents"
one=1
two=2
printf "\x3${one},${two}${str}\x30"\
(without spaces this string messes up)
printf "\x3${one},${two}%s\x30" "${str}" # outputs "5 cents"
So it ends up being either " 25 cents " (wrong), or "5 cents" (wrong x 2)... It should be:
25 cents
I've tried just about everything, escaping the variables, putting them in quotes and no luck. Evidently there's a correct way to handle this that I'm unaware of, so any help is great - thanks.
If what you are trying to do is insert mIRC colour codes into a string -- and you would have made it easier to be helped if you had said so -- then you need to be aware of two things:
The C-style hexadecimal escapes interpreted by Gnu printf have the format \x followed by two hexadecimal digits. (You can use just one digit, but only if the next character is not a hexadecimal digit. So it's better to think of it as always being two digits.) A control-C (character code 3) is written \x03. x30 through \x39 are the character codes for the digits 0 through 9. The translation of the escape code is done by printf, not by the shell, so parameter substitution happens first. So if the value of $one is one, printf "\x3${one}" will be expanded to printf "\x31" by the shell, and then printf will print the digit 1. I presume that is not what you want, since there are obviously much less round-about ways to insert the value of a variable, which don't limit the variable to be a single decimal digit.
Not all printf implementations handle hexadecimal escapes, and not all shells have a built-in printf. So while you can use \x03 with bash, you might find that it is not portable. All printf implementations should handle octal escapes, though, and 3 is still 3 in octal, but now you need three digits: \003.
The mIRC colour codes have the form control-C followed by up to two numbers separated by a comma. These numbers have a maximum of two digits, and if the next character after the colour code is a digit, you must use the two-digit form. (Coincidentally similar to the hex escape codes above, but it is truly just a coincidence.) So if you wanted the text 25 with foreground colour 3 and background colour 1, you would need to send ^C1,0225^C; if you sent ^C1,225^C, that would be interpreted as foreground colour 1 and background colour 25 (which is not a valid colour code), with the text being 5.
This is mentioned in the mIRC documentation linked above:
Note: if you want to color text that begins with numbers, this syntax requires that you specify the color value as two digits.
So a better printf invocation might be:
printf "\003%02d,%02d%s\003" "$one" "$two" "$str"
Note: It is, of course, possible that my guess about what string you are seeking to produce is completely wrong; it is just a guess based on an off-hand comment which was not deleted. If so, and if you are serious about getting your question answered, I strongly suggest you provide a clearer explanation of precisely what byte-string you are attempting to produce with your printf statement.

Preventing converting string into octal number in Ruby

Assume we have following ruby code
require 'yaml'
h={"key"=>[{"step1"=>["0910","1223"]}]}
puts h.to_yaml
"0910" is a string
but after to_yaml conversion, string turns into octal number.
---
key:
- step1:
- 0910
- '1223'
the problem is I cannot change h variable. I receive it from outside, and I need to solve problem without changing it.
You are mistaken that there is an octal number in your YAML output. The YAML spec refers to octal on two occasions, and both clearly indicate that an octal number in a YAML file starts with 0o (which is a similar to what Ruby and newer versions of Python use for specifying octal; Python also dropped the support for 0 only octals in version 3, Ruby doesn't seem to have done that—yet).
The custom to indicate octal integers starting with a 0 only, has been proven confusing in many language and was dropped from the YAML specification six years ago. It might be that your parser still supports it, but it shouldn't.
In any case the characters 8 and 9 can never occur in an integer represented as an octal number, so in this case there can be no confusion that that unquoted scalar is a number.
The string 1223 could be interpreted as a normal integer, therefore it must always be represented as a quoted string scalar.
The interesting thing would be to see what happens when you dump the string "0708". If your YAML library is up-to-date with the spec (version 1.2) it can just dump this as an unquoted scalar. Because of the leading zero that is not followed by o (or x) there can be no confusion that this could be an octal number (resp. hexadecimal) either, but for compatibility with old parsers (from before 2009) your parser might just quote it to be on the safe side.
According the the YAML spec numbers prefixed with a 0 signal an octal base (as does in Ruby). However 08 is not a valid octal number, so it doesn't get quoted.
When you come to load this data from the YAML file, the data appears exactly as you need.
0> h={"key"=>[{"step1"=>["0910","1223"]}]}
=> {"key"=>[{"step1"=>["0910", "1223"]}]}
0> yaml_h = h.to_yaml
=> "---\nkey:\n- step1:\n - 0910\n - '1223'\n"
0> YAML.load(yaml_h)
=> {"key"=>[{"step1"=>["0910", "1223"]}]}
If you can't use the data in this state perhaps you could expand on the question and give more detail.
There was a similar task.
I use in secrets.yml:
processing_eth_address: "0x5774226def39e67d6afe6f735f9268d63db6031b"
OR
processing_eth_address: <%= "\'#{ENV["PROCESSING_ETH_ADDRESS"]}\'" %>
My Ruby doesn't do this octal conversion but I had a similar issue with dates. I used to_yaml(canonical: true) to get around this issue. It's more verbose but it's correct.
{"date_of_birth" => "1991-02-29"}.to_yaml
=> "---\ndate_of_birth: 1991-02-29\n"
{"date_of_birth" => "1991-02-29"}.to_yaml(canonical: true)
=> "---\n{\n ? \"date_of_birth\"\n : \"1991-02-29\",\n}\n"

Using parameter in Fortran90 format descriptor

How can I use parameters in format descriptor in Fortran90?
I want to make a matrix, say square(n*n), but I want to make it general. So, I declared a parameter like this: integer,parameter::n=3 (say n is 3 here)
Then after inputting the elements of the matrix in a do/implied do loop, I want to write it with the format function as follows:
format(ni5)
But it gives the error: Unexpected element 'N' in format string
Any simple way to solve this??
Little-known fact: format specifiers can be constructed at runtime as a character string. This means that you can programmatically define the format specifier and pass it to the write statement.
CHARACTER(len=30) fm
INTEGER :: i
i = 3
WRITE(fm,'(a,i1,a)')"(",i,"i5)"
WRITE(*,fm)1,2,3
In the above, we are generating the actual format specifier with the number of integers that you need to print for the given situation (i), then using that string as the format of the second write statement.
I very rarely see people use this trick, and its possible that it is not defined in the actual standard, but it does work in gfortran.

Change integer into hex Ruby

I am currently porting a perl project to ruby and all has been going fine until I reached this pack statement.
$move .= pack('W', int($length));
I understand what it's trying to do, but I can't find any documentation on the 'W' option for perls pack method. So it is a bit hard to find a suitable replacement for ruby.
What this statement does is takes the integer, and converts it to a big endian hex format (I believe).
For example the integer 290 is converted to 0x122, and is then stored as "2201" in the variable $move
Although I cannot confirm that because I can't find documentation on 'W' although it would make sense based on what the rest of the project is doing.
Does anyone know a ruby replacement method that would do the same?
edit: As per a comment below I have found it with some help.
W An unsigned char value (can be greater than 255).
Since the format's introduction in 5.10, pack says:
W An unsigned char value (can be greater than 255).
For example, the following are equivalent:
pack('W', 0x2660)
chr(0x2660)
"\x{2660}"
For all values of $i, length(pack('W', $i)) is one.
What's the size of a character (string element) in Ruby? Are they 8 bits like C, or larger like Java (16) and Perl (32 or 64)?
If they are limited to 8 bits, there is no direct equivalent of that code in Ruby. You'll need to use an array instead of a string.
If Ruby's character are wide enough to contain the numbers in question (e.g. 290), then a look through the Ruby docs reveals the following:
i.chr

Fortran FORMAT statement

I am trying to read in the following in line:
110134458.602 7 20957861.900
My format line is currently as follows:
READ(7,110,END=999) L1,C1,D1
write(*,*) L1,C1,D1
110 FORMAT(F14.3,1x,F1.0,2x,F14.3)
However the output I am receiving is:
110134458.60200000 7.0000000000000000 20957861.899999999
Why do I have so many decimal places and why is the final value not match?
Thank you!
It looks that you are reading the values correctly. With list-directed IO for the output the compiler will typically use the maximum number of digits for the numeric type. Not all decimal values will have exact finite precision binary equivalents -- that is probably what you are seeing for the 3rd number. If you use a format statement for the output, specifying fewer digits, the value will get rounded and appear correct.

Resources