What's the equivalent of GLSL's uintBitsToFloat in WGSL? - glsl

I am converting a random number generator from GLSL to WGSL, and it uses the function uintBitsToFloat. What's the equivalent in WGSL? Example use, from https://www.shadertoy.com/view/Mt3cRX:
uint Hash_Wang(uint key) {
key = (key ^ 61u) ^ (key >> 16u);
key = key + (key << 3u);
key = key ^ (key >> 4u);
key = key * 0x27D4EB2Du;
key = key ^ (key >> 15u);
return key;
}
float UniformUintToFloat(uint u) {
// IEEE-754: 2^-32 = 0x2F800000
return float(u) * uintBitsToFloat(0x2F800000u);
}

Solution
The equivalent in WGSL is bitcast<T>. For this specific case where I want to convert to f32:
bitcast<f32>(0x2F800000u)
Apart from this, as explained here, WGSL supports hexadecimal floats, so 0x1p-126f should do the job as the smallest non-subnormal number.

Related

Fastest way to transpose 16 word array

I have the following code:
void shuffle_words(WORD_TYPE* _state)
{
WORD_TYPE temp[DATA_SIZE];
temp[7] = _state[0];
temp[12] = _state[1];
temp[14] = _state[2];
temp[9] = _state[3];
temp[2] = _state[4];
temp[1] = _state[5];
temp[5] = _state[6];
temp[15] = _state[7];
temp[11] = _state[8];
temp[6] = _state[9];
temp[13] = _state[10];
temp[0] = _state[11];
temp[4] = _state[12];
temp[8] = _state[13];
temp[10] = _state[14];
temp[3] = _state[15];
memcpy_s(_state, temp, DATA_SIZE * WORD_SIZE);
}
int prp(WORD_TYPE* data, WORD_TYPE key)
{
shuffle_words(data);
key = round_function<14, 15>(data, key);
key = round_function<13, 14>(data, key);
key = round_function<12, 13>(data, key);
key = round_function<11, 12>(data, key);
key = round_function<10, 11>(data, key);
key = round_function<9, 10>(data, key);
key = round_function<8, 9>(data, key);
key = round_function<7, 8>(data, key);
key = round_function<6, 7>(data, key);
key = round_function<5, 6>(data, key);
key = round_function<4, 5>(data, key);
key = round_function<3, 4>(data, key);
key = round_function<2, 3>(data, key);
key = round_function<1, 2>(data, key);
key = round_function<0, 1>(data, key);
key = round_function<15, 0>(data, key);
return key;
}
I would like to know if there is a faster way to perform the shuffle_words operation. I have seen questions about matrix transposition, but those appear to be focused on situations where the matrix is either large or multidimensional.
My array will always be 16 words in size, and the prp function will be applied multiple times on the same array, one immediately after another. This leads me to believe simply accessing elements in the transposed order without actually transposing them is an option.
The round_function already writes data to the array, if it would be more efficient to move the shuffle into that it would be acceptable. Here is the code for that, in case it's needed:
template <int left_index, int right_index>
WORD_TYPE round_function(WORD_TYPE* state, WORD_TYPE key)
{
WORD_TYPE left, right;
left = state[left_index];
right = state[right_index];
key ^= right;
right = rotate_left<ROTATION_AMOUNT>(right + key + left_index);
key ^= right;
key ^= left;
left += right >> (BIT_WIDTH / 2);
left ^= rotate_left<(left_index % BIT_WIDTH) ^ ROTATION_AMOUNT>(right);
key ^= left;
state[left_index] = left;
state[right_index] = right;
return key;
}
I thought of supplying a destination index to round_function, but doing so overwrites bytes that have yet to be operated on, which destroys the data at the destination index.
What is the most efficient way to perform the word transposition step?
Is it possible to efficiently perform shuffle_words without temporary storage and memcpy? Will the compiler optimize this for me if I leave it as is?
edit:
For a sample input of 16 null words, I got the following output:
5390936987981438580
7289498000187791405
11630888819098945478
4862561973623181657
11364775727483781365
1302861686580238483
10934483497681452460
376472396741801
17443576244438476890
17213444377027086447
15287741771379858051
16772715748200046576
6216997191100954620
16389751604649919423
2033403819063771136
14517213842436349075
I used these #defines:
#define ROTATION_AMOUNT 41
#define BIT_WIDTH 64
#define DATA_SIZE 16
typedef unsigned long long WORD_TYPE;
I am ok if functionality is modified slightly if an increase in efficiency can be obtained.
Yes!
void shuffle_words(WORD_TYPE* _state) {
WORD_TYPE temp = _state[0];
_state[0] = _state[11];
_state[11] = _state[8];
_state[8] = _state[13];
_state[13] = _state[10];
_state[10] = _state[14];
_state[14] = _state[2];
_state[2] = _state[4];
_state[4] = _state[12];
_state[12] = _state[1];
_state[1] = _state[5];
_state[5] = _state[6];
_state[6] = _state[9];
_state[9] = _state[3];
_state[3] = _state[15];
_state[15] = _state[7];
_state[7] = temp;
}

TEdit Input Validation on C++ Builder XE8

I am very new to C++ Builder XE8.
I want the minimum and maximum length of numbers that must be typed is as much as six numbers, also I need to make sure that only number is entered (0 is exception), and not an alphabetic character, backspace, punctuation, etc.
I would also like to produce an error box if anything other than a number is entered.
I've tried a few combinations of codes, three of which can be seen below, but none of those codes works.
Any help would sure be appreciated!
(1).
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
Edit1->MaxLength = 6;
if (!((int)Key == 1-9)) {
ShowMessage("Please enter numerals only");
Key = 0;
}
}
(2).
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
Edit1->MaxLength = 6;
if (Key <1 && Key >9) {
ShowMessage("Please enter numerals only");
Key = 0;
}
}
(3).
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
Edit1->MaxLength = 6;
if( Key == VK_BACK )
return;
if( (Key >= 1) && (Key <= 9) )
{
if(Edit1->Text.Pos(1-9) != 1 )
ShowMessage("Please enter numerals only");
Key = 1;
return;
}
}
TEdit has a NumbersOnly property:
Allows only numbers to be typed into the text edit.
Set it to true and let the OS handle the validation for you. But, if you want to validate it manually, use this:
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, System::WideChar &Key)
{
// set this at design-time, or at least
// in the Form's constructor. It does not
// belong here...
//Edit1->MaxLength = 6;
if( Key == VK_BACK )
return;
if( (Key < L'0') || (Key > L'9') )
{
ShowMessage("Please enter numerals only");
Key = 0;
}
}
Check out TMaskEdit: http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/idh_useop_textcontrols_xml.html
TMaskEdit is a special edit control that validates the text entered against a mask that encodes the valid forms the text can take. The mask can also format the text that is displayed to the user.
EDIT: To set a minimum length
void __fastcall TForm1::MaskEdit1Exit(TObject *Sender)
{
if (MaskEdit1->Text.length() < 6)
{
//your error message, or throw an exception.
}
}

cannot read string result from MYSQL

I want to have an if else statement inside a loop when getting the results of
data from mysql .. However the if statement cannot read the result.. but the codes are perfectly I see the problem in my if else condition.
here is my Code from my asynctask
for (int i = 0; i < markers.length(); i++) {
JSONObject c = markers.getJSONObject(i);
// Storing each json item in variable
Double LAT = c.getDouble(TAG_LAT);
Double LNG = c.getDouble(TAG_LNG);
String color = c.getString(TAG_STATUS);
String red = "ongoing";
String green = "firedout";
if (color == red){
LatLng position = new LatLng(LAT, LNG);
status.add(new MarkerOptions()
.title(color)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
.position(position));
// adding HashList to ArrayList
}
if (color == green){
LatLng position = new LatLng(LAT, LNG);
status.add(new MarkerOptions()
.title(color)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))
.position(position));
// adding HashList to ArrayList
}
}
Equivalent String values are not guaranteed to be unique in Java. In other words, there can be two String objects with exactly the same value.
String s1 = "ongoing";
String s2 = new String(s1);
System.out.println(s1 == s2); // false!
System.out.println(s1.equals(s2)); // true :)
Therefore, you must say:
if (red.equals(color)) {
// do something
}

ConcurrentHashMap in JDK7 code explanation (scanAndLockForPut)

The source codes of the method scanAndLockForPut in ConcurrentHashMap in JDK7 says:
private HashEntry<K,V> scanAndLockForPut(K key, int hash, V value) {
HashEntry<K,V> first = entryForHash(this, hash);
HashEntry<K,V> e = first;
HashEntry<K,V> node = null;
int retries = -1; // negative while locating node
while (!tryLock()) {
HashEntry<K,V> f; // to recheck first below
if (retries < 0) {
if (e == null) {
if (node == null) // speculatively create node
node = new HashEntry<K,V>(hash, key, value, null);
retries = 0;
}
else if (key.equals(e.key))
retries = 0;
else
e = e.next;
}
else if (++retries > MAX_SCAN_RETRIES) {
lock();
break;
}
else if ((retries & 1) == 0 &&
(f = entryForHash(this, hash)) != first) {
e = first = f; // re-traverse if entry changed
retries = -1;
}
}
return node;
}
I understand what the codes mean, but what I don't is this else if entry:
else if ((retries & 1) == 0 && (f = entryForHash(this, hash)) != first)
My question is:
Why do we have to do "(retries & 1) == 0"?
EDIT:
I kind of figure it out. It's all because the constant MAX_SCAN_RETRIES:
static final int MAX_SCAN_RETRIES = Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1;
In single core processor, MAX_SCAN_RETRIES = 1. So the second time the thread steps into the loop "while(tryLock)", it doesn't have to check whether the first node was changed.
However, in multi cores processor, this will behave like checking whether the first node is changed every 2 times in the while loop.
Is the above explanation correct?
Let's break this down:
1:
(retries & 1) == 0
This returns 1 for odd numbers, 0 for even numbers. Basically, to get past, there's a 1 in 2 chance, if the number is even.
2:
f = entryForHash(this, hash)
f is a temporary variable used to store the value of the latest entry in the segment.
3:
(/* ... */) != first
Checks if the value changed. If it did, it would move the current entry to the start, and re-iterate the linked nodes again in attempt to acquire the lock.
I've asked this question on the concurrency-interest mailing list, and the author(Doug Lea) himself replied:
Yes. We need only ensure that staleness is eventually detected.
Alternating the head-checks works fine, and simplifies use of
the same code for both uni- and multi- processors.
link
So I think this is the end of this question.
I think there are some bugs for the method!
first let us see the put method:
final V put(K key, int hash, V value, boolean onlyIfAbsent) {
HashEntry<K,V> node = tryLock() ? null :
scanAndLockForPut(key, hash, value);//1. scanAndLockForPut only return
// null or a new Entry
V oldValue;
try {
HashEntry<K,V>[] tab = table;
int index = (tab.length - 1) & hash;
HashEntry<K,V> first = entryAt(tab, index);
for (HashEntry<K,V> e = first;;) {
if (e != null) {
K k;
if ((k = e.key) == key ||
(e.hash == hash && key.equals(k))) {
oldValue = e.value;
if (!onlyIfAbsent) {
e.value = value;
++modCount;
}
break;
}
e = e.next;
}
else {
// 2. here the node is null or a new Entry
// and the node.next is the origin head node
if (node != null)
node.setNext(first);
else
node = new HashEntry<K,V>(hash, key, value, first);
int c = count + 1;
if (c > threshold && tab.length < MAXIMUM_CAPACITY)
rehash(node);
else
setEntryAt(tab, index, node);//3. finally, the node become
// the new head,so eventually
// every thing we put will be
// the head of the entry list
// and it may appears two equals
// entry in the same entry list.
++modCount;
count = c;
oldValue = null;
break;
}
}
} finally {
unlock();
}
return oldValue;
}
step: 1. scanAndLockForPut only return null or a new Entry.
step: 2. the node eventualy a new Entry, and the node.next is the origin head node
step: 3. finally, the node become the new head,so eventually every thing we put will be the head of the entry list and it may appears two equals entry in the same entry list when the concurrentHashMap works in a concurrent environment.
That is my opinion, and I am not exactly sure about whether it is right or not. So I hope you all give me some advice,thanks a lot!!

Why is this encrypted message damaged?

I use the following code to encrypt a string with a key, using the 3-DES algorithm:
private bool Encode(string input, out string output, byte[] k, bool isDOS7)
{
try
{
if (k.Length != 16)
{
throw new Exception("Wrong key size exception");
}
int length = input.Length % 8;
if (length != 0)
{
length = 8 - length;
for (int i = 0; i < length; i++)
{
input += " ";
}
}
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.Zeros;
des.Key = k;
ICryptoTransform ic = des.CreateEncryptor();
byte[] bytePlainText = Encoding.Default.GetBytes(input);
MemoryStream ms = new MemoryStream();
CryptoStream cStream = new CryptoStream(ms,
ic,
CryptoStreamMode.Write);
cStream.Write(bytePlainText, 0, bytePlainText.Length);
cStream.FlushFinalBlock();
byte[] cipherTextBytes = ms.ToArray();
cStream.Close();
ms.Close();
output = Encoding.Default.GetString(cipherTextBytes);
}
catch (ArgumentException e)
{
output = e.Message;
//Log.Instance.WriteToEvent("Problem encoding, terminalID= "+objTerminalSecurity.TerminalID+" ,Error" + output, "Security", EventLogEntryType.Error);
return false;
}
return true;
}
I send the output parameter as is over to a WCF http-binding webservice, and I noticed that the actual encoded string looks different, it looks like there are some \t and \n but the charachters are about the same.
What is going on, why does the server get a different encoded string?
Usually cipher text is base64 encoded in an effort to be binary safe during transmission.
Also I would not use 3DES with ECB. That is awful, you must have copy pasted this from somewhere. Use AES with cbc mode and think about adding a cmac or hmac.