Pull to refresh
4
0

Пользователь

Send message
На C++ и Java можно написать классы для знаковых целых и за счет перегрузки операторов ввести проверки. Это может решить проблему, но производительность значительно снизится.

Конечно, было бы здорово получить поддержку проверок как в C#. Там и с производительностью все не плохо, однако по умолчанию проверка операций все равно отключена.
Можете привести пример кода?
Накидал проверку:
Код
//#include <iostream> //для С++ компилятора
#include  <stdio.h> //для C компилятора
#include <limits.h>


int
add_orig(int x, int y, int *z)
{
    int r = x + y;
    if (x > 0 && y > 0 && r < x) {
        return 0;
	}
    if (x < 0 && y < 0 && r > x) {
        return 0;
	}
    *z = r;
    return 1;
}

int add_new1(int x, int y, int *z)
{
	if (y >= 0 && x > INT_MAX - y)
    return 0;
	if (y < 0 && x < INT_MIN - y)
    return 0;
	*z = x+y;
	return 1;
}

int add_new2(int x, int y, int *z)
{
	if (y >= 0 && x > INT_MAX - y)
    return 0;
	if (y < 0 && x < INT_MIN - y)
    return 0;
	if (x >= 0 && y > INT_MAX - x)
    return 0;
	if (x < 0 && y < INT_MIN - x)
    return 0;
	*z = x+y;
	return 1;
}

void test(int a, int b)
{
    int x, y, z;
    x=a;
    y=b;
    printf("Orig: ");
    if (add_orig(x, y, &z)) {
        printf("%d\n", z);
		} else {
        printf("overflow!\n");
	}
    printf("New1: ");
	if (add_new1(x, y, &z)) {
        printf("%d\n", z);
		} else {
        printf("overflow!\n");
	}
	printf("New2: ");
	if (add_new2(x, y, &z)) {
        printf("%d\n", z);
		} else {
        printf("overflow!\n");
	}
}

int main(int argc, char *argv[])
{
    printf("Test1 17,42\n");
    test(17,42);
    printf("\nTest2 2000000000,1500000000\n");
    test(2000000000, 1500000000);
    return 0;
}

Результаты
Результаты для clang 3.8.0:
Test1 17,42
Orig: 59
New1: 59
New2: 59

Test2 2000000000,1500000000
Orig: -794967296
New1: overflow!
New2: overflow!


Результат для Microsoft ® C/C++ Optimizing Compiler Version 19.00.23506 for x64:
Test1 17,42
Orig: 59
New1: 59
New2: 59

Test2 2000000000,1500000000
Orig: overflow!
New1: overflow!
New2: overflow!


Результат для gcc версия 6.4.0 (GCC) под сигвином:
Test1 17,42
Orig: 59
New1: 59
New2: 59

Test2 2000000000,1500000000
Orig: overflow!
New1: overflow!
New2: overflow!


Результат для gcc версия 5.4.0:
Test1 17,42
Orig: 59
New1: 59
New2: 59

Test2 2000000000,1500000000
Orig: overflow!
New1: overflow!
New2: overflow!



Работает. Спасибо!
Хорошая статья. Спасибо за перевод!

Может кто-нибудь подсказать правильную реализацию int add(int x, int y, int *z) без использования более длинных типов?
Русскоязычные технической направленности


Англоязычные технической направленности


Просто интересное, никак не DIY
  • ensemb — популярно про физику, изложение в развлекательной форме


Рукоделие
С Магмой есть нюанс — неразбериха с таблицами замен.Есть рекомендации, но нет единого стандарта. Существует легенда о слабых таблицах.

С параноей предлагаю бороться путем последовательного шифрования двумя шифрами конкурирующих контор… Нет, лучше тремя! А еще лучше пятью! Магма — TEA — AES — Кузнечик — Raiden
В итоге я так и не смог понять, как и где можно найти кварцевые резонаторы настолько мерзейшего качества. Но, видимо, в Китае возможно всё.

Там не крварц используется, а керамический резонатор. Например, CSTCE16M0V53-R0. Базовая точность 0.5% Если посчитать 0.5% от 16МГц, то получится 80КГц. И это без учета отклонений до 0.3% при изменении температуры.
Главная проблема китайских резонаторов — негерметичность крышки. Эта самая крышка еще и отваливается с завидной регулярностью, что приводит к выходу резонатора из строя.
Основной плюс таких резонаторов — встроенные конденсаторы, что уменьшает BOM. И цены на китайские резонаторы довольно вкусные, получается дешевле кварца.

Information

Rating
Does not participate
Registered
Activity