Is there a good way to format a minus number with zero padding in Erlang? The following works well for unsigned value, but for minus value, zero is padded before the sign.
io:format("~4..0B~n", [42]).
0042
ok
io:format("~4..0B~n", [-42]).
0-42
ok
What I have in mind is the following format.
(ruby)
1.9.2-p290 :004 > sprintf("%05d", -42)
"-0042"
1.9.2-p290 :005 > sprintf("%05d", 42)
"00042"
(python)
>>> "%05d" % -42
'-0042'
>>> "%05d" % 42
'00042'
I've referred to the following questions, but haven't been able to find one which talks about minus values.
How to format a number with padding in Erlang
Erlang: How to transform a decimale into a Hex string filled with zeros
Currently there is no direct way of doing this in Erlang. The padding char is for the whole field and their is no way of padding just the actual value. The precision field is used for the base with which to print the integer. Using ~w does not help as the precision behaves the same way as the field width. I myself have trying to do this very recently and not come up with a simple solution.
EDIT:
If you look here https://github.com/rvirding/luerl/blob/develop/src/luerl_string.erl#L156 there is a function format which does a C sprintf like formatted output. It is written for a Lua implementation and is probably more general than you need, but look at the function print_integer and print_float for the base handling. I have some better functions on the go which I should be pushing this evening.
Related
Is there an erlang equivalent of codePointAt from js? One that gets the code point starting at a byte offset, without modifying the underlying string/binary?
You can use bit syntax pattern matching to skip the first N bytes and decode the first character from the remaining bytes as UTF-8:
1> CodePointAt = fun(Binary, Offset) ->
<<_:Offset/binary, Char/utf8, _/binary>> = Binary,
Char
end.
Test:
2> CodePointAt(<<"πr²"/utf8>>, 0).
960
3> CodePointAt(<<"πr²"/utf8>>, 1).
** exception error: no match of right hand side value <<207,128,114,194,178>>
4> CodePointAt(<<"πr²"/utf8>>, 2).
114
5> CodePointAt(<<"πr²"/utf8>>, 3).
178
6> CodePointAt(<<"πr²"/utf8>>, 4).
** exception error: no match of right hand side value <<207,128,114,194,178>>
7> CodePointAt(<<"πr²"/utf8>>, 5).
** exception error: no match of right hand side value <<207,128,114,194,178>>
As you can see, if the offset is not in a valid UTF-8 character boundary, the function will throw an error. You can handle that differently using a case expression if needed.
First, remember that only binary strings are using UTF-8 in Erlang. Plain double-quote strings are already just lists of code points (much like UTF-32). The unicode:chardata() type represents both of these kinds of strings, including mixed lists like ["Hello", $\s, [<<"Filip"/utf8>>, $!]]. You can use unicode:characters_to_list(Chardata) or unicode:characters_to_binary(Chardata) to get a flattened version to work with if needed.
Meanwhile, the JS codePointAt function works on UTF-16 encoded strings, which is what JavaScript uses. Note that the index in this case is not a byte position, but the index of the 16-bit units of the encoding. And UTF-16 is also a variable length encoding: code points that need more than 16 bits use a kind of escape sequence called "surrogate pairs" - for example emojis like 👍 - so if such characters can occur, the index is misleading: in "a👍z" (in JavaScript), the a is at 0, but the z is not at 2 but at 3.
What you want is probably what's called the "grapheme clusters" - those that look like a single thing when printed (see the docs for Erlang's string module: https://www.erlang.org/doc/man/string.html). And you can't really use numerical indexes to dig the grapheme clusters out from a string - you need to iterate over the string from the start, getting them out one at a time. This can be done with string:next_grapheme(Chardata) (see https://www.erlang.org/doc/man/string.html#next_grapheme-1) or if you for some reason really need to index them numerically, you could insert the individual cluster substrings in an array (see https://www.erlang.org/doc/man/array.html). For example: array:from_list(string:to_graphemes(Chardata)).
I'm creating a Lua script which will calculate a temperature value then format this value as a 4 digit hex number which must always be 4 digits. Having the answer as a string is fine.
Previously in C I have been able to use
data_hex=string.format('%h04x', -21)
which would return ffeb
however the 'h' string formatter is not available to me in Lua
dropping the 'h' doesn't cater for negative answers i.e
data_hex=string.format('%04x', -21)
print(data_hex)
which returns ffffffeb
data_hex=string.format('%04x', 21)
print(data_hex)
which returns 0015
Is there a convenient and portable equivalent to the 'h' string formatter?
I suggest you try using a bitwise AND to truncate any leading hex digits for the value being printed.
If you have a variable temp that you are going to print then you would use something like data_hex=string.format("%04x",temp & 0xffff) which would remove the leading hex digits leaving only the least significant 4 hex digits.
I like this approach as there is less string manipulation and it is congruent with the actual data type of a signed 16 bit number. Whether reducing string manipulation is a concern would depend on the rate at which the temperature is polled.
For further information on the format function see The String Library article.
I am doing some simple hex comparison in an if statement.
0x7843E0 is greater than 0x780000 but the code below doesn't output anything.
if {"780000" <= "7843E0"} {
puts "True!"
}
>>
Omitting the trailing 0 works fine however.
if {"780000" <= "7843E"} {
puts "True!"
}
>>> True!
There must be something wrong with the trailing 0 but I don't understand what it is. Any ideas?
You're having problems with the way the expr command parses numbers. (The rest of Tcl is more relaxed about this.) The issue is that:
"780000" gets interpreted as a decimal integer.
"7843E0" gets interpreted as a double precision floating point number. (Compare with 1.2e10; the number parser thinks it is fitting the same sort of pattern.)
"780000" gets interpreted as a decimal integer.
"7843E" gets interpreted as a non-numeric string (a fallback because no numeric interpretation is legal).
The <= operator will happily compare two numbers if they're both numbers, or two strings if at least one of the parameters to it is non-numeric. (Yes, this does make for weird semantics occasionally.) Moreover, he expr command is eager to interpret values as numbers if it possibly can, but it still has Tcl's syntactic rules for what actually is numeric, and what type of numeric those things are. When you don't stick to the rules, it gets a bit odd.
To get a value interpreted as hexadecimal, you have to either prefix its string representation with 0x (e.g., 0x7843E0) or force things with a command such as scan with %x:
scan "780000" %x a
scan "7843E0" %x b
if {$a <= $b} {
puts "True"
}
Forcing interpretations with scan is considered to be one of the best ways of dealing with this, as that only writes canonical values into variables. (If you'd been wanting to handle octal numbers, or were wanting to really always be decimal, you'd use %o and %d respectively; %f is for floating-point numbers.)
Finally, if you're really comparing values as strings with normal ASCII-like rules, look at string compare instead of using <= directly.
if {[string compare $input1 $input2] <= 0} {
...
}
Im converting binary to decimal and Im converting Decimal to binary. My problem is Length of the binary integer. For example:
Convertx("001110",2,10) = 14
Convertx("14",10,2) = 1110
But length of the binary is NOT constant, So How can I get exact original binary with zeros front of it? How can I get "001110" instead of "1110" ?
I m using this function in Delphi 7. -> How can I convert base of decimal string to another base?
The function you are using returns a string that is the shortest length required to express the value you have converted.
Any zeroes in front of that string are simply padding - they do not alter the binary value represented. If you need a string of a minimum length then you need to add this "padding" yourself. e.g. if you want a binary representation of a "byte" (i.e. 8 binary digits) then the minimum length you would need is 8:
binStr := Convertx("14",10,2);
while Length(binStr) < 8 do
binStr := '0' + binStr;
If you need the exact number of zeroes that were included in the "padding" of some original binary value when converting from binary to decimal and then back to "original" binary again, then this is impossible unless you separately record how many padding zeroes there were or the length of the original string, including those zeroes.
i.e. in your example, the ConvertX function has no idea (and now way to figure out) that the number "14" it is asked to convert to binary was originally converted from a 6 digit binary string with 2 leading zeroes, rather than an 8 digit binary with 4 leading zeroes (or a 16 digit binary with 12 leading zeroes, etc etc).
What you are hoping for is impossible. Consider
Convertx('001110', 2, 10)
and
Convertx('1110', 2, 10)
These both return the same output, 14. At that point there is no way to recover the length of the original input.
The way forward is therefore clear. You must remember the length of the original binary, as well as the equivalent decimal. However, once you have reached that conclusion then you might wonder whether there is an even simpler approach. Just remember the original binary value and save yourself having to convert back from decimal.
I'am new to Maxima and would like to use it for Denavit-Hartenberg matrices (consists of a lot of cos and sin terms). The problem is, that maxima does not simplify the following expression:
ex: x*cos(pi);
I expect, that Maxima simplifies ex to -x. How can this been done? (ratsimp(ex) and trigsimp(ex) have no effects)
In Maxima's dialect, the correct name of the constant is %pi. With it, it should simplify correctly.
As others have said, %pi is the correct name of the constant in Maxima. pi is simply rendered as π in GUIs like wxMaxima because all Greek letters are (you can have a variable named "π", which has nothing to do with the value of the constant π=3.14159...).
By the way, other predefined constants are written with the % character as well, such as for example
%e (=exp(1))
%i (=sqrt(-1))
%phi (the golden section)
The manual's index lists all % candidates.
Note that other useful constants that can not be expressed by digits, such as inf or false do not have the percent character.