Right now I have made my own funcs to do bitwise and + not but then I saw the bit library and tried to use it but it doesn't work how I imagined, it returns a large decimal instead of the binary bit and so my question is actually a few.
First: how to do bitwise AND on binary number using the bit32 library.
10110111
11000100 = 10000100
Second: How to calculate the ipv4 broadcast address by adding the network address and the wildcard mask in binary form using the bit32 library
192.168.1.0 + 31 = 192.168.1.31
11000000.10100000.00000001.00000000
00000000.00000000.00000000.00011111 = 11000000.10100000.00000001.00011111
I am assuming that your bitwise and / not functions take string arguments.
Numbers can be represented in multiple ways.
The number 110101, which is in base two, has the same value as 53, which is in base 10.
When you say
x=123
Lua converts 123 into its binary representation, 1111011, which it then stores in memory as bits.
When you say
print(x)
Lua goes into memory, grabs x, which is 1111011, and then converts it into its more human-readable base 10 representation, and you see
123
The bitwise functions you wrote performs bit operations on strings which display the binary representation of a number like "1111011". the bit32 library performs bit operations on numbers, which display the decimal representation of a number like 123.
In Lua, "1001001" is a string, but if arithmatic operations are performed on it, it treats it as if it were a number written in base 10. So when you do
bit32.band("101","110")
the bit32.band function interprets its arguments as one-hundred-one and one-hundred-ten.
You must first convert your binary strings into numbers:
bit32.band(tonumber("101",2), tonumber("110",2))
Related
A simple question that turned out to be quite complex:
How do I turn a float to a String in GForth? The desired behavior would look something like this:
1.2345e fToString \ takes 1.2345e from the float stack and pushes (addr n) onto the data stack
After a lot of digging, one of my colleagues found it:
f>str-rdp ( rf +nr +nd +np -- c-addr nr )
https://www.complang.tuwien.ac.at/forth/gforth/Docs-html-history/0.6.2/Formatted-numeric-output.html
Convert rf into a string at c-addr nr. The conversion rules and the
meanings of nr +nd np are the same as for f.rdp.
And from f.rdp:
f.rdp ( rf +nr +nd +np – )
https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Simple-numeric-output.html
Print float rf formatted. The total width of the output is nr. For
fixed-point notation, the number of digits after the decimal point is
+nd and the minimum number of significant digits is np. Set-precision has no effect on f.rdp. Fixed-point notation is used if the number of
siginicant digits would be at least np and if the number of digits
before the decimal point would fit. If fixed-point notation is not
used, exponential notation is used, and if that does not fit,
asterisks are printed. We recommend using nr>=7 to avoid the risk of
numbers not fitting at all. We recommend nr>=np+5 to avoid cases where
f.rdp switches to exponential notation because fixed-point notation
would have too few significant digits, yet exponential notation offers
fewer significant digits. We recommend nr>=nd+2, if you want to have
fixed-point notation for some numbers. We recommend np>nr, if you want
to have exponential notation for all numbers.
In humanly readable terms, these functions require a number on the float-stack and three numbers on the data stack.
The first number-parameter tells it how long the string should be, the second one how many decimals you would like and the third tells it the minimum number of decimals (which roughly translates to precision). A lot of implicit math is performed to determine the final String format that is produced, so some tinkering is almost required to make it behave the way you want.
Testing it out (we don't want to rebuild f., but to produce a format that will be accepted as floating-point number by forth to EVALUATE it again, so the 1.2345E0 notation is on purpose):
PI 18 17 17 f>str-rdp type \ 3.14159265358979E0 ok
PI 18 17 17 f.rdp \ 3.14159265358979E0 ok
PI f. \ 3.14159265358979 ok
I couldn't find the exact word for this, so I looked into Gforth sources.
Apparently, you could go with represent word that prints the most significant numbers into supplied buffer, but that's not exactly the final output. represent returns validity and sign flags, as well as the position of decimal point. That word then is used in all variants of floating point printing words (f., fp. fe.).
Probably the easiest way would be to substitute emit with your word (emit is a deferred word), saving data where you need it, use one of available floating pint printing words, and then restoring emit back to original value.
I'd like to hear the preferred solution too...
There are many answers on how to separate fractional part from integer part in float, but is there a way to efficiently assemble float from 2 integer numbers? For example, 123 and 012345 will produce 123.012345 (doesn't have to be exact)
This question was after reading "How to parse space-separated floats in c++ quickly" where the linked answer uses the following approach to assemble floats:
using strtol extract number from left of the '.' (will be the integer), extract the number on the right of the '.' (will be the fractional part)
using the length of second number, multiply the number by 0.1, 0.01, 0.001, 0.0001 depending on its length
add left to right.
Is there a more efficient approach (in c++ 14 and above)? Currently it requires multiplication and addition, which can play role when assembling hundreds of millions of such numbers.
... Something that would set exponent and mantissa directly?
Edit:
regarding distinguishing 012345 from 12345 when it's in the int form, the author of the above link used strtol, so I can compute the length we travelled while parsing. So I would know that the number is 6 digits long (for example), even though I got 12345
What is the number format length in bytes?
This is a "multi type" data format. Is it 4 bytes? 8 bytes? How much? How can I get it programmatically? Does the length depend on the OS/processor type?
Here https://www.lua.org/pil/2.3.html the documentation says this is a double precision type. That is, it has 64 bits. Am I right?
Like #Roddy said, it's slightly complicated with the integer type. Moreover, it depends on how your Lua is compiled.
Basically, in Lua 5.3, there are two types, the integer type lua_Integer and the number type lua_Number. You can get their lengths programatically from within Lua by parsing a chunk header:
local chunk = string.dump(function() end)
print("lua_Integer", chunk:byte(16))
print("lua_Number", chunk:byte(17))
Typically both lengths will be 8 bytes. However on some embedded platforms you can find Luas where the lua_Number type is a float (4 bytes), a 32 bit integer or even weirder things.
It depends on the version of Lua, and of course, how it's compiled.
5.3 has true integers, typically 64 bits. https://www.lua.org/manual/5.3/manual.html
The type number uses two internal representations, or two subtypes,
one called integer and the other called float.
...
Standard Lua uses 64-bit integers and double-precision (64-bit)
floats, but you can also compile Lua so that it uses 32-bit integers
and/or single-precision (32-bit) floats.
Earlier versions always use 64-bit double-precision floating point, which effectively accurately represents up to 52-bit integers. Your link... https://www.lua.org/pil/2.3.html
according to the Lua reference (for integers)
In case of overflows in integer arithmetic, all operations wrap around, according to the usual rules of two-complement arithmetic. (In other words, they return the unique representable integer that is equal modulo 2^64 to the mathematical result.)
and for floating point
With the exception of exponentiation and float division, the arithmetic operators work as follows: If both operands are integers, the operation is performed over integers and the result is an integer. Otherwise, if both operands are numbers or strings that can be converted to numbers (see §3.4.3), then they are converted to floats, the operation is performed following the usual rules for floating-point arithmetic (usually the IEEE 754 standard), and the result is a float.
Lua as a language does not define what you ask for. The data type used for representing numbers may differ from version to version (note that the link to the free online version of "Programming in Lua" is about Lua 5.0), but primarily this is defined by the way Lua is compiled, as others already said.
Look at luaconf.h for all the details.
Regarding your actual problem (converting hex-string to numbers), you could look at the result of tonumber() on various input strings, compared to known results:
function hexConvertibeBytes()
local i, s = 0, ''
repeat
i, s = i + 1, s .. 'FF'
local n = tonumber( s, 16 )
until n ~= 256^i - 1
return i - 1
end
We can use string.pack as follows:
s = string.pack("J",0)
number_of_bytes = #s
I'm going to create an API which contains money amounts. I was wondering what the best practices are, or whether someone has some good or bad experiences with certain formats.
should we transmit base units or minor units? (amount vs amount_cents)
should we represent the numbers as integers / decimals or as strings?
I've seen the following two possibilities:
send amounts as a string like so: "5.85" (a string with base units)
send amounts in their minor unit: 585 (an integer which expresses the amount in the minor unit)
I'm going back and forth between those two. So I went out to check what other APIs use and came up with the following list:
Stripe: integer with minor units
Braintree: string with base units
Google Wallet: string with base units
Paypal: string with base units
Amazon Payments: string with base units
The Currency Cloud: string with base units
2checkout: string with base units
Adyen: integer with minor units
Dwolla: decimal with base units
GotoBilling: weird heuristics! "Amount may be formatted with or without a decimal. If no decimal is given two (2) decimal places are assumed (1.00 = 100)"
GoCardless: string with base units
Intuit: decimal with base units in requests, string with base units in responses
Klarna: integer with minor units
MasterCard: integer with minor units
Paynova: string with base units
Rogers Catalyst: string with base units
WePay: string with base units
Venmo: decimal with base units
So, out of 18 sampled APIs, 4 are using minor units, 13 are using base units and 1 is using a hard-to-comprehend mixture. And within the 13 who use base units, 10 are transmitting them as quoted strings, 3 as unquoted decimals (actually 2 and a half if you look at Intuit).
I personally feel uncomfortable having to parse a string like "8.20", because if you parse this it becomes "8.19999999..." if you make the mistake to use floats. So I'm leaning towards sending integers only. But I don't think this is a great argument, and I see that generally APIs tend to go with base units as strings.
Do you have any good arguments for/against each format?
Integers will eat the dot, that's one less byte :D Integers will have a max_int, do you have anyone rich enough that may overflow?
People that will parse a currency string as float will turn the int to float anyway.
If you send binary data, integer will be much smaller than a string and the way to go. If you send xml anyway, you might as well define it a string (the file is probably compressed before sending right?), try to make it "currency" type as opposed to listing it as a full string though.
Which datatype is the best depends on your usage. For calculations integers or doubles are going to be faster, skipping the parsing step.
If sending the data through networks is your goal you're better off with strings.
That said, any functionality should be realizable using either method.
In the Erlang shell, I can do the following:
A = 300.
300
<<A:32>>.
<<0, 0, 1, 44>>
But when I try the following:
B = term_to_binary({300}).
<<131,104,1,98,0,0,1,44>>
<<B:32>>
** exception error: bad argument
<<B:64>>
** exception error: bad argument
In the first case, I'm taking an integer and using the bitstring syntax to put it into a 32-bit field. That works as expected. In the second case, I'm using the term_to_binary BIF to turn the tuple into a binary, from which I attempt to unpack certain bits using the bitstring syntax. Why does the first example work, but the second example fail? It seems like they're both doing very similar things.
The difference between in a binary and a bitstring is that the length of a binary is evenly divisible by 8, i.e. it contains no 'partial' bytes; a bitstring has no such restriction.
This difference is not your problem here.
The problem you're facing is that your syntax is wrong. If you would like to extract the first 32 bits from the binary, you need to write a complete matching statement - something like this:
<<B1:32, _/binary>> = B.
Note that the /binary is important, as it will match the remnant of the binary regardless of its length. If omitted, the matched length defaults to 8 (i.e. one byte).
You can read more about binaries and working with them in the Erlang Reference Manual's section on bit syntax.
EDIT
To your comment, <<A:32>> isn't just for integers, it's for values. Per the link I gave, the bit syntax allows you to specify many aspects of binary matching, including data types of bound variables - while the default type is integer, you can also say float or binary (among others). The :32 part indicates that 32 bits are required for a match - that may or may not be meaningful depending on your data type, but that doesn't mean it's only valid for integers. You could, for example, say <<Bits:10/bitstring>> to describe a 10-bit bitstring. Hope that helps!
The <<A:32>> syntax constructs a binary. To deconstruct a binary, you need to use it as a pattern, instead of using it as an expression.
A = 300.
% Converts a number to a binary.
B = <<A:32>>.
% Converts a binary to a number.
<<A:32>> = B.