Я могу предотвратить целочисленное переполнение в C# с помощью неподписанного сдвига вправо?

Вот еще одно решение, использующее defaultdict

df = pd.DataFrame({'name': {0: 'A', 1: 'A', 2: 'B', 3: 'C', 4: 'B', 5: 'A'},
 'v1': {0: 'A1', 1: 'A2', 2: 'B1', 3: 'C1', 4: 'B2', 5: 'A2'},
 'v2': {0: 'A11', 1: 'A12', 2: 'B12', 3: 'C11', 4: 'B21', 5: 'A21'},
 'v3': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6}})


output = defaultdict(dict)

for lst in df.values:
    try:
        output[lst[0]][lst[1]].update({lst[2]:lst[3]})
    except KeyError:
        output[lst[0]][lst[1]] = {}
    finally:
        output[lst[0]][lst[1]].update({lst[2]:lst[3]})

output

или:

output = defaultdict(dict)

for row in df.values:

    item1,item2 = row[0:2]

    if output.get(item1, {}).get(item2) == None:
        output[item1][item2] = {}

    output[item1][item2].update({row[2]:row[3]})
6
задан Kevin Fairchild 14 November 2008 в 19:23
поделиться

6 ответов

unchecked((largeValue1 + largeValue2) >> 1) другая опция.

См. документацию для ключевого слова непроверенного.

3
ответ дан 16 December 2019 в 21:48
поделиться

Можно сделать это этот путь:

  x = largeValue1;
  y = largeValue2; 
  return (x&y)+((x^y)/2);

Это - битовое жонглирование способ получить среднее число двух целых чисел без переполнения.

Если Вы хотите Вас, может заменить подразделение два со сдвигом разряда, но компилятор сделает это для Вас так или иначе.

2
ответ дан 16 December 2019 в 21:48
поделиться

Для не мелочных придирок но Вы имеете в виду "целочисленное переполнение", а не "переполнение буфера".

Я не знаю C#, таким образом, может быть иначе, но Вы могли подражать неподписанному сдвигу, просто маскируя от главного бита: (x>> 1) и 0x80000000

0
ответ дан 16 December 2019 в 21:48
поделиться
int alwaysPositive = (largeValue1 >> 1) + (largeValue2 >> 1) + (largeValue1 & largeValue2 & 0x01);

Идея позади вышеупомянутого состоит в том, что, если Вы предварительно делите результаты перед добавлением их, затем Вы избежите переполнения, поскольку оба старших бита будут сброшены. Вы затем добавляете некоторую небольшую логику исправления для увеличивания значения тем, если оба были положительны (округляют в меньшую сторону). Если Вы только заботитесь, был ли любой положителен (округляют) затем, Вы могли бы изменить его на

int alwaysPositive = (largeValue1 >> 1) + (largeValue2 >> 1) + ((largeValue1 | largeValue2) & 0x01);
3
ответ дан 16 December 2019 в 21:48
поделиться

Вы могли использовать единицы:

uint alwaysPositive = (uint)(largeValue1 + largeValue2) / 2;
0
ответ дан 16 December 2019 в 21:48
поделиться
try
{
    checked { alwaysPositive3 = (largeValue1 + largeValue2); }
}
catch (OverflowException ex)
{
   // Corrective logic
}
0
ответ дан 16 December 2019 в 21:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: