How does ActionScript's writeInt work with Integers? - actionscript

I wanted to know how does writeInt treat a 32 bit unsigned or a signed integer passed to it?
It is easy to understand that how it works with a hexadecimal number. Util.Print will print the corresponding ASCII Characters.
0x41424344 will be broken down into 4 1 byte characters, A, B, C and D.
It seems like its different when an integer is passed to writeInt.
for instance,
var test: ByteArray = new ByteArray();
test.writeInt(0x41424344); // prints ABCD
test.writeInt(2590463591); // prints gVg
test.writeInt(1119885898); // prints BÀJ
I am unclear how the Util.Print function treats the integers written into the ByteArray by writeInt.
The characters, gVg do not correspond to the integer number, 2590463591
According to the definition of writeInt here:
http://livedocs.adobe.com/livecycle/es/sdkHelp/common/langref/flash/utils/ByteArray.html#writeInt%28%29
It states that it works with a 32 Bit Signed Integer.
If someone can elaborate over how it translates the integers to characters, it would be helpful.
EDIT: And how does it handle negative integers?
For instance,
test.writeInt(-11338743); // prints ÿRü
So,
-11338743 = 0xFF52FC09
is that correct?
Thanks.

If you interpret encoded bytes as ASCII
dec hex ascii
1094861636 = 0x41424344 = ABCD
2590463591 = 0x9A675667 = gVg
1119885898 = 0x42C01A4A = BÀJ
Also, note that int vs unsigned int would implement different functions:
var test:ByteArray = new ByteArray();
test.writeInt(0x41424344);
test.writeUnsignedInt(0x41424344);

Related

Systemverilog string variable as format specifier for $display/$write

I'm trying to create a variable format specifier for use in $display/$write. I've tried a large number of things, but here is what I have at the moment.
What I want to end up with is: $display(format_var,data_1,data_2), where the format string is pre-calculated using $sformatf or other.
Code:
module test;
function void pprint(input int data_1,input int field_1,input int data_2,input int field_2);
string format;
begin
format = $sformatf("%0d'h%%%0dx,%0d'h%%%0dx",field_1,field_1/4,field_2,field_2/4);
$display("format = %s",format);
$display(format,data_1,data_2);
end
endfunction
initial
begin
pprint(5,8,73737229,128);
$stop;
end
endmodule
The output I expect is:
format = 8'h%2x,128'h%32x
8'h05,128'h000000000000000000000000465240D
The output I get is:
format = 8'h%2x,128'h%32x
8'h%2x,128'h%32x 5 73737229
What do I need to do? The simulator is Vivado 2020.3
Later:
Trying more things, the following function does do what I want. My conclusion is that $display/$write can't take a variable as the format string, but $sformatf can.
function void pprint(input int data_1,input int field_1,input int data_2,input int field_2);
string format;
string outstr;
begin
format = $sformatf("%0d'h%%%0dx,%0d'h%%%0dx",field_1,field_1/4,field_2,field_2/4);
$display("format = %s",format);
$display("%s",$sformatf(format,data_1,data_2));
end
endfunction
Try:
function void pprint(
input logic [4095:0] data_1,
input int field_1,
input logic [4095:0] data_2,
input int field_2 );
string format;
format = $sformatf("%0d'h%%%0dh,%0d'h%%%0dh",
field_1, (field_1+3)/4,
field_2, (field_2+3)/4 );
$display("format = %s",format);
$display($sformatf(format,data_1,data_2));
endfunction
This should give you the output:
format = 8'h%02h,128'h%032h
8'h05,128'h000000000000000000000000465240D
Adding a zero between the % and digit could tells the simulator to pad the upper bits with zeros.
For some reason $display(format,data_1,data_2) did not use the format on simulators on edaplayground, but it did work with $sformatf so I simply nested it.
I needed to increase the bit width of the input data otherwise it would show leading zeros over 8 digits. Adjust if necessary.
Adding 3 to the field is for handling non multiples of 4. It will always round down after division.
According to section 21.3.3 Formatting data to a string of the SystemVerilog LRM, only $sformat and $sformatf have a specific formatting argument that can be a string literal or string variable. All other output tasks like $display treat any string literal argument as format specifiers and do not interpret the strings inside string variables for formatting.

Is there a Dart function to convert List<int> to Double?

I'm getting a Bluetooth Characteristic from a Bluetooth controller with flutter blue as a List. This characteristic contains weight measurement of a Bluetooth scale. Is there a function to convert this list of ints to a Double?
I tried to find some background on float representations by reading the IEEE 754 standard. There is the dart library typed_data but I am new to dart and have no experience with this lib.
Example:
I have this List: [191, 100, 29, 173] which is coming from a bluetooth controller as a IEEE754 representation for a float value.
Now i believe i have to convert each int to hex and concat these values: bf 64 1d ad
Next thing need to do is convert this to double, but i cannot find a function to convert hex to double. Only int.parse("0xbf641dad").
I guess your mean to convert the list of ints to a list of floats, not to a single float, right?
First, dart has no type called float. Instead it has type double. To convert it, you can use the map() function:
var listInt = [1, 2, 3];
var listDouble = list.map((i) => i.toDouble()).toList();
Had this same issue.
I think you mean how do you make the four bytes into a float32 ?
I needed to do the same thing.
you will want to do something like this:
first take the List value as a byte buffer, then take the byte data, then you can use the getFloat32 function.
ByteBuffer buffer = new Int8List.fromList(value_in).buffer;
ByteData byteData = new ByteData.view(buffer);
result = byteData.getFloat32(0);
Just be a little aware that the order of bytes from the Bluetooth may be back to front, as the convention varys.
Also you will need the typed_data library:
import 'dart:typed_data'; //for data formatting
I'm trying to go in the other direction now . . . for the obvious reason.
You may need this:
double parseHexString(String hexStr, bool littleEndian){
if(hexStr.length % 2 != 0){
return 0;
}
if(littleEndian == true){
List<int> bytes = hex.decode(hexStr).reversed.toList();
hexStr = hex.encode(bytes);
}
var byteConvert = ByteData(12);
byteConvert.setInt64(0, int.parse(hexStr,radix: 16));
return byteConvert.getFloat64(0);}
And demo :
double lat = parseHexString("0000004069665E40",true);
//lat = 121.60017395019531
If you already have:
int.parse("0xbf641dad")
I don't see why this wouldn't work:
int.parse("0xbf641dad").toDouble();
I used dart:typed_data for this:
import 'dart:typed_data';
List<int> intList = [191, 100, 29, 173];
double asFloat = ByteData.view(Uint8List.fromList(List.from(intList)).buffer).getFloat32(0, Endian.little);
Library reference: https://api.dart.dev/be/136883/dart-typed_data/dart-typed_data-library.html

Dart: convert decimal to hex

I've been searching for a way to convert decimal numbers to hexadecimal format in the Dart programming language.
The hex.encode method in the HexCodec class, for example, cannot convert the decimal 1111 (which has a hex value of 457) and instead gives an exception:
FormatException: Invalid byte 0x457. (at offset 0)
How do I convert a decimal number to hex?
int.toRadixString(16)
does that.
See also https://groups.google.com/a/dartlang.org/forum/m/#!topic/misc/ljkYEzveYWk
Here is a little fuller example:
final myInteger = 2020;
final hexString = myInteger.toRadixString(16); // 7e4
The radix just means the base, so 16 means base-16. You can use the same method to make a binary string:
final binaryString = myInteger.toRadixString(2); // 11111100100
If you want the hex string to always be four characters long then you can pad the left side with zeros:
final paddedString = hexString.padLeft(4, '0'); // 07e4
And if you prefer it in uppercase hex:
final uppercaseString = paddedString.toUpperCase(); // 07E4
Here are a couple other interesting things:
print(0x7e4); // 2020
int myInt = int.parse('07e4', radix: 16);
print(myInt); // 2020

Convert string to base64 byte array in swift and java give different value

Incase of android everything is working perfectly. I want to implement same feature in iOS too but getting different values. Please check the description with images below.
In Java/Android Case:
I tried to convert the string to base64 byte array in java like
byte[] data1 = Base64.decode(balance, Base64.DEFAULT);
Output:
In Swift3/iOS Case:
I tried to convert the string to base64 byte array in swift like
let data:Data = Data(base64Encoded: balance, options: NSData.Base64DecodingOptions(rawValue: 0))!
let data1:Array = (data.bytes)
Output:
Finally solved:
This is due to signed and unsigned integer, meaning unsigned vs signed (so 0 to 255 and -127 to 128). Here, we need to convert the UInt8 array to Int8 array and therefore the problem will be solved.
let intArray = data1.map { Int8(bitPattern: $0) }
In no case should you try to compare data on 2 systems the way you just did. That goes for all types but specially for raw data.
Raw data are NOT presentable without additional context which means any system that does present them may choose how to present them (raw data may represent some text in UTF8 or some ASCII, maybe jpeg image or png or raw RGB pixel data, it might be an audio sample or whatever). In your case one system is showing them as a list of signed 8bit integers while the other uses 8bit unsigned integers for the same thing. Another system might for instance show you a hex string which would look completely different.
As #Larme already mentioned these look the same as it is safe to assume that one system uses signed and the other unsigned values. So to convert from signed (Android) to unsigned (iOS) you need to convert negative values as unsigned = 256+signet so for instance -55 => 256 + (-55) = 201.
If you really need to compare data in your case it is the best to save them into some file as raw data. Then transfer that file to another system and compare native raw data to those in file to check there is really a difference.
EDIT (from comment):
Printing raw data as a string is a problem but there are a few ways. The thing is that many bytes are not printable as strings, may be whitespaces or some reserved codes but mostly the problem is that value of 0 means the end of string in most cases which may exist in the middle of your byte sequence.
So you already have 2 ways of printing byte by byte which is showing Int8 or Uint8 corresponding values. As described in comment converting directly to string may not work as easy as
let string = String(data: data, encoding: .utf8) // Will return nil for strange strings
One way of converting data to string may be to convert each byte into a corresponding character. Check this code:
let characterSequence = data.map { UnicodeScalar($0) } // Create an array of characters from bytes
let stringArray = characterSequence.map { String($0) } // Create an array of strings from array of characters
let myString = stringArray.reduce("", { $0 + $1 }) // Convert an array of strings to a single string
let myString2 = data.reduce("", { $0 + String(UnicodeScalar($1)) }) // Same thing in a single line
Then to test it I used:
let data = Data(bytes: Array(0...255)) // Generates with byte values of 0, 1, 2... up to 255
let myString2 = data.reduce("", { $0 + String(UnicodeScalar($1)) })
print(myString2)
The printing result is:
!"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
Then another popular way is using a hex string. It can be displayed as:
let hexString = data.reduce("", { $0 + String(format: "%02hhx",$1) })
print(hexString)
And with the same data as before the result is:
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
I hope this is enough but in general you could do pretty much anything with array of bytes and show them. For instance you could create an image treating bytes as RGB 8-bit per component if it would make sense. It might sound silly but if you are looking for some patterns it might be quite a witty solution.

How to store long in a Swift array?

I got a couple user IDs I want to send in an array, but can't figure out the correct Swift 3 syntax for creating an array with very long integers. I tried casting, # prefix and using as AnyObject, but that did not work.
let idArray = [10211420262370680, 10211420262370680]
Error: integer literal overflows when stored into int
What is the correct way to create an array with such long integers?
Try this instead:
let idArray: [UInt64] = [10_211_420_262_370_680, ...]
As a back of the envelope calculation, every 10 bits buys you 3 decimal digits. For instance, UInt32 maxes out around 4_000_000_000 and so on.
By the way, the underscores _ above are just syntax sugar for big number literals ;-)
Signed long's array:
let signed64BitIntegerArray: [Int64] = [-10211420262370680, 10211420262370680]
Unsigned long's array:
let unsigned64BitIntegerArray: [UInt64] = [ 10211420262370680, 10211420262370680]
If you need C interop/FFI, use CLong or CUnsignedLong.

Resources