- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
// https://github.com/TigerVNC/tigervnc/blob/8c6c584377feba0e3b99eecb3ef33b28cee318cb/java/com/jcraft/jsch/Buffer.java#L65-L85
public void putInt(int val) {
tmp[0]=(byte)(val >>> 24);
tmp[1]=(byte)(val >>> 16);
tmp[2]=(byte)(val >>> 8);
tmp[3]=(byte)(val);
System.arraycopy(tmp, 0, buffer, index, 4);
index+=4;
}
public void putLong(long val) {
tmp[0]=(byte)(val >>> 56);
tmp[1]=(byte)(val >>> 48);
tmp[2]=(byte)(val >>> 40);
tmp[3]=(byte)(val >>> 32);
System.arraycopy(tmp, 0, buffer, index, 4);
tmp[0]=(byte)(val >>> 24);
tmp[1]=(byte)(val >>> 16);
tmp[2]=(byte)(val >>> 8);
tmp[3]=(byte)(val);
System.arraycopy(tmp, 0, buffer, index+4, 4);
index+=8;
}
Жабовское байтоебство (судя по всему это такой ntohl) из реализации VNC.
Вот интересно, в жабке-то unsigned типов нет нихера, но почему-то сделали unsigned двоичный сдвиг (>>>), который работает для этих встроенных signed типов как если б это были unsigned. А как насчет unsigned умножения и деления (сложение и вычитание - то один хер, без разницы, если у нас two's complement)?
j123123 28.01.2019 08:28 # +3
byte: The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation.
short: The short data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As with byte, the same guidelines apply: you can use a short to save memory in large arrays, in situations where the memory savings actually matters.
int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of 2^31-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2^32-1. Use the Integer class to use int data type as an unsigned integer. See the section The Number Classes for more information. Static methods like compareUnsigned, divideUnsigned etc have been added to the Integer class to support the arithmetic operations for unsigned integers.
long: The long data type is a 64-bit two's complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2^64-1. Use this data type when you need a range of values wider than those provided by int. The Long class also contains methods like compareUnsigned, divideUnsigned etc to support arithmetic operations for unsigned long.
j123123 28.01.2019 08:30 # +2
bormand 28.01.2019 08:41 # 0
j123123 28.01.2019 08:46 # 0
__m128i _mm_add_epi8 (__m128i a, __m128i b)
bormand 28.01.2019 09:02 # 0
Интересно, зачем тогда вообще это правило про каст мелочи в int перед операциями? Оно же как чайник Рассела. Ни доказать ни опровергнуть.
bormand 28.01.2019 09:12 # 0
j123123 28.01.2019 09:12 # 0
uint8_t in[8];
uint16_t out[4];
out[0] = in[0] * in[1];
out[1] = in[2] * in[3];
out[2] = in[4] * in[5];
out[3] = in[6] * in[7];
bormand 28.01.2019 10:18 # 0
bormand 28.01.2019 09:04 # 0
Эмуляция через signed чтобы не трогать JVM?
bormand 28.01.2019 08:34 # 0
JIyHHblu_nemyx 28.01.2019 13:29 # 0
Пусть x_u, y_u –— временные беззнаковые переменные (типа uint16_t), хранящие битовые копии x, y (типа int16_t).
Тогда x_u = x + pow(2,16)*h(x<0), где h –— функция Хевисайда;
y_u = y + pow(2,16)*h(y<0);
x_u*y_u = x*y + pow(2,16)*(y*h(x<0) + x*h(y<0)) + pow(2,32)*h(x<0)*h(y<0).
Выразим x и y через x_u и y_u соответственно и найдём значение x*y через беззнаковые переменные:
x*y = x_u*y_u - pow(2,16)*(y_u*h(x<0) + x_u*h(y<0)) +
+ pow(2,32)*h(x<0)*h(y<0)*(-1 + 1 + 1).
От последнего слагаемого толку нет, ибо его значение за пределом разрядности.
Итого:
https://ideone.com/DDqPGb
JIyHHblu_nemyx 28.01.2019 13:36 # 0
Теперь всё правильно:
https://ideone.com/7TE4No
JIyHHblu_nemyx 28.01.2019 13:48 # 0
Пусть x_s, y_s –— временные знаковые переменные (типа int16_t), хранящие копии x,y (типа uint16_t).
Тогда x_s = x - pow(2,16)*h(x>T-1);
y_s = y - pow(2,16)*h(y>T-1);
где T = pow(2,15) –— постоянная Тараса для данного типа данных.
x_s*y_s = x*y - pow(2,16)*(y*h(x>T-1) + x*h(y>T-1)) + pow(2,32)*h(x>T-1)*h(y>T-1).
Аналогично выразим x и y через x_s и y_s и получим:
x*y = x_s*y_s + pow(2,16)*(y_s*h(x>T-1) + x_s*h(y>T-1)) + pow(2,32)*h(x>T-1)*h(y>T-1)*(-1+1+1).
JIyHHblu_nemyx 28.01.2019 13:52 # 0
https://ideone.com/hinhoN
bormand 28.01.2019 14:32 # 0
JIyHHblu_nemyx 28.01.2019 14:35 # 0
Но тогда придётся x1.s и y1.s предварительно кастануть в числа вдвое большей разрядности.
JIyHHblu_nemyx 28.01.2019 14:42 # 0
bormand 28.01.2019 14:43 # 0
bormand 28.01.2019 14:34 # 0
Rooster 28.01.2019 14:46 # +1
ЩЫ. это не лисп, я прост пероритеты забуа Перемножить модули и поставить соответствующий знак.
Rooster 28.01.2019 14:48 # 0
bormand 28.01.2019 14:50 # 0
Rooster 28.01.2019 14:55 # 0
gost 28.01.2019 15:00 # +1
Rooster 28.01.2019 15:18 # +1
Вроде раьотает.
JIyHHblu_nemyx 28.01.2019 20:28 # 0
T + T = 0 (по модулю 2 в степени n).
Или так:
T = -T (по модулю 2 в степени n).
Rooster 28.01.2019 17:46 # 0
bormand 28.01.2019 18:37 # 0
gost 28.01.2019 18:56 # 0
bormand 28.01.2019 19:14 # 0
bormand 28.01.2019 19:02 # +1
Rooster 28.01.2019 19:37 # +2
Rooster 28.01.2019 14:56 # 0
j123123 28.01.2019 15:36 # 0
хотя тут могут быть ньюансы с endian
bormand 28.01.2019 15:58 # 0
j123123 28.01.2019 16:10 # 0
bormand 28.01.2019 22:24 # 0
На темплейтах, чтобы конпелятор мог оптимизнуть под конкретную длину?
j123123 29.01.2019 05:51 # 0
bormand 29.01.2019 07:54 # 0
bormand 29.01.2019 08:15 # 0
gost 29.01.2019 10:38 # 0
guest8 28.01.2019 16:31 # −999
bormand 28.01.2019 17:11 # 0
Rooster 28.01.2019 17:30 # 0
bormand 28.01.2019 17:35 # 0
guest8 28.01.2019 17:39 # −999
Rooster 28.01.2019 17:52 # 0
JIyHHblu_nemyx 28.01.2019 21:41 # 0
А если будешь использовать встроенный ассемблер в «gcc» или в «clang», то знак «%» ещё нужно удвоить, чтобы по ошибке не подставился мокрос.
bormand 28.01.2019 22:22 # 0
guest8 28.01.2019 23:01 # −999
bormand 28.01.2019 23:13 # 0
gueest8 28.01.2019 23:15 # 0
bormand 28.01.2019 23:22 # 0
JIyHHblu_nemyx 28.01.2019 23:14 # 0
gueest8 28.01.2019 23:16 # 0
bormand 28.01.2019 23:34 # 0
JIyHHblu_nemyx 29.01.2019 01:14 # +1
bormand 28.01.2019 08:35 # 0
Ну иначе байтоёбить было бы совсем уныло.