Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Как сравнивать беззнаковые числа?

Здравствуйте!
Я ввожу число 12312312312, функции getuint должна поместить в свой первый параметр 1231231231,
но она помещает туда 3722377720.
Я думаю, так происходит, потому что здесь *pn < *pn*10+(c-'0') компьютер считает числа знаковыми.
Как сделать, чтобы сравнивались беззнаковые числа?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
 
unsigned int getuint(unsigned int *pn);
 
int main()
{
    unsigned int x=1231231231;
    printf("getuint(&x)= %i\n",getuint(&x));
    printf("%u\n",x);
    return 0;
}
 
 
unsigned int getuint(unsigned int *pn)
{
    int c;
 
    while(isspace(c=getchar()))
        ;
    if (!isdigit(c) && c!=EOF && c!='+') 
        return 0;
    if (c=='+')
        c=getchar();
    if (isdigit(c))
       for(*pn=0;isdigit(c) && *pn < *pn*10+(c-'0');c=getchar())
            *pn=*pn*10+(c-'0');
    else if (c!=EOF)
        return 0;
    return c;
}
Ответ:
Сообщение от quwy
В результате все выражение становится знаковым.
У меня все выражение без знаковое.

Решение нашёл.
Спасибо за ответ.
Вопрос: Вычитание целых беззнаковых чисел большой размерности

Здравствуйте. Подскажите принцип вычитания целых беззнаковых чисел, например, размерностью 5 байт.
ASM
1
2
3
4
5
6
.data
  a db 4Bh, 15E, 6Eh, 0A1h, 34h ; 5 байт 
  b db 0B4h, 23h, 6Ch, 0C2h, 6Dh ; 5 байт
  r db 6 dup(?) ;
 .code
 start:
Ответ:
Сообщение от Dick777
Подскажите принцип вычитания целых беззнаковых чисел
"Глава 10. АРИФМЕТИЧЕСКИЕ КОМАНДЫ" "Для чего нужны команды ADC и SBB? Арифметика одинарной и многократной точности"
Вопрос: Заменить нулями числа, превосходящие заданное значение для массива 16-разрядных беззнаковых чисел

Заменить нулями числа, превосходящие заданное значение для массива 16-разрядных беззнаковых чисел. Как это реализовать?
Ответ:
  1. выводишь содержимое массива на экран
  2. сравниваешь элементы массива с заданным значением
  3. если меньше или равно, тогда переходишь к пункту 5
  4. если больше, тогда обнуляешь элемент
  5. увеличиваешь индекс массива, если пройден не весь массив, тогда возвращаешься к пункту 2
  6. выводишь содержимое массива на экран
  7. выходишь из программы
Вопрос: Составить программу. Сравнивающую два числа

Составить программу. Сравнивающую два числа введенных римскими цифрами . ( с помощью функции). Заранее благодарю.
Ответ: kentok25, что значит сравнить? Дать ответ "равно/не равно", или показать, какое число больше, а какое - меньше?

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function ToDecimal(s : string) : integer;
begin
  var D := Arr(' I', ' 1', ' V', ' 5', ' X', '10', ' L', '50', ' C', '100', ' D', '500', ' M', '1000').
           Batch(2).ToDictionary(v -> v.ElementAt(0).Trim(), v -> v.ElementAt(1).Trim().ToInteger());
           
  Result := 0;
  for var i := 1 to s.Length do
    if (i < s.Length) and (d[s[i]] < d[s[i + 1]]) then Dec(Result, d[s[i]]) else inc(Result, d[s[i]])
 
end;
 
function CompareRomans(r1, r2 : string) : Integer;
begin
  Result := ToDecimal(r2).CompareTo(ToDecimal(r1));
end;
 
begin
  writeln(Arr('Первое число больше', 'Числа равны', 'Второе число больше')
             [Sign(CompareRomans('DCCCLXIV', 'DCCCLXIV')) + 1]);
end.
, например
Вопрос: Не во всех IDE корректно сравнивает вещественные числа?

Язык Си.
Не могу понять почему в двух средах (C++Builder 6 и BDS 2006) сравнение вещественных чисел не удаётся...

Код C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <conio.h>
#include <stdio.h>
 
int main() {
  int a=4,b=2,c=3;
  double s = (100*c+10*b+a)*47/36.0;
 
  // задать сравнение вещественных чисел
 
  // работает везде (C++Builder 6, BDS 2006, MS VS 2010 Ultimate)
  if (423.0 == s) {
    printf("TEST #1\n");
  }
 
  // не работает в C++Builder 6 и BDS 2006; интересует только эта краткая запись на сравнение,
  // т. е. без использования дополнительной переменной s
  if (423.0 == (100*c+10*b+a)*47/36.0) {
    printf("TEST #2\n");
  }
 
  printf("Press any key to exit ...");
  _getch();
 
  return 1;
}
Ответ:
Сообщение от keep_clear
как тогда их сравнить – перевести в строку и тогда сравнивать?
не нужно переводить в строку, нужно определить точность сравнения, т.е. принять какое-либо маленькое число (одна десятая/сотая/тысячная/ и т.д.) и сранивать абсолютное значение разности сравниваемых величин с данной точностью. Например
Код C
1
2
3
4
5
double epsilon = 1e-6; // одна миллионная
if (fabs(423.0 - (100*c+10*b+a)*47/36.0) < epsilon)
{
   // TODO
}
Вопрос: Как умножить положительное целое беззнаковое число на 2?

Здравствуйте! я начала учить ассемблер и у меня появился вопрос. Как умножить положительное целое без знаковое число на 2? Подскажите пожалуйста буду очень благодарна!!))
Ответ: Somebody, proc3nt, как не стыдно... человек ассемблер изучать начал, а ему сразу костыли в руки

IAnnaI, наберите в гугле " команда MUL ассемблер. То что вам предложили выше не умножение как таковое. Лучше освойте его сейчас, когда результат задания можно проверить даже в уме, что бы понять как работает именно умножение.
Вопрос: Быстрая сортировка на четность нечетность чисел

Есть собственный список. А так же реализован алгоритм быстрой сортировки.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        public void Sort(IMyComparer<T> comparer)
        {
            Sort(0, Count - 1, comparer);
        }
 
        public void Sort(int low, int high, IMyComparer<T> comparer)
        {
            ThrowIfIsOutOfRange(low, high);
 
            T pivot = array[low + (high - low) / 2];
            // also like (high+low)/2 but don't owerflow array on big data
 
            int i = low;
            int j = high;
 
            Partition(ref i, ref j, pivot, comparer);
 
            if (i < high)
                Sort(i, high, comparer);
 
            if (low < j)
                Sort(low, j, comparer);
        }
 
        private void Partition(ref int i, ref int j, T pivot, IMyComparer<T> comparer)
        {
            while (i < j)
            {
                while (comparer.Compare(array[i], pivot) < 0)
                    i++;
                while (comparer.Compare(array[j], pivot) > 0)
                    j--;
                
                if (i <= j)
                {
                    T temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                    i++;
                    j--;
                }
            }
        }


Где IMyComparer у нас интерфейс с одним методом. (да знаю, в таком случае лучше использовать делегат, но у нас задание реализовать с помощью интерфейса).
Кликните здесь для просмотра всего текста
C#
1
2
3
4
    interface IMyComparer<T>
    {
        int Compare(T left, T right);
    }


Ну и сама сортировка выглядит следующим образом:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        static void Main(string[] args)
        {
            MyList<int> list = new MyList<int>();
            Random rnd = new Random();
            for (int i = 0; i <= 10; i++)
            {
                list.Add(rnd.Next(10));
            }
 
            MyComparer myComperer = new MyComparer();
            list.Sort(myComperer);
 
            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine("{0}", list[i]);
            }
 
            Console.ReadKey(true);
        }
 
        sealed class MyComparer : IMyComparer<int>
        {
            public int Compare(int left, int right)
            {
                //Discending sort
                return -left.CompareTo(right);
            }
        }


Собственно вопрос как в данном случае реализовать сортировку четных не четных чисел. Сам алгоритм сортировки должен быть в функции Compare. Я думаю, что проблема в реализации, ведь мы в сортировке сравниваем некое число с опорным элементом. Как обойти? И есть ли толк от быстрой сортировки в данном случае, ведь нам по идее надо будет разделить в последствии наш массив на две части, и отсортировать его подчасти.
В идеале - массив делят на две части, левая например с четными елементами, правая с нечетными. Потом уже каждая часть сортируется по отдельности по возрастанию.
У кого какие идеи?
Ответ:
Сообщение от kol
Мы в a и b записываем результат логической операции.
Побитовой логической операции.

Сообщение от kol
Почему нечетное число возвращает 1, а чётное 0?
Потому что числа в компьютере представлены в двоичной системе счисления, где в каждом разряде может быть либо 1, либо 0. А поскольку каждое второе число нечетное, постольку в двоичном представлении у каждого второго числа (нечетного) самый младший бит будет всегда единицей:
010 = 00002
110 = 00012
210 = 00102
310 = 00112
410 = 01002

И так далее ad infinitum.

Сообщение от kol
Дальше у меня начинается каламбур, относительно того как будет происходить разбивка на под части с последующем вызовом рекурсии, ведь опорный элемент в последствии измениться.
Так это уже забота алгоритма сортировки.
Задача реализации IComparer заключается только в том, чтобы описать отношение порядка для двух элементов множества.
Вопрос: Сравнение двух вещественных чисел

Почему не работает сравнение при числах:
2.85730505
2.85729861

C++
1
2
3
4
    bool isEqual( float x, float y )
    {
        return std :: fabs( x - y ) < std::numeric_limits<float> :: epsilon();
    }
std::numeric_limits<float> :: epsilon() слишком маленькое? Можно увеличить? Или как лучше сравнивать вещественные числа?
Ответ:
Сообщение от Bretbas
Почему не работает сравнение при числах:
2.85730505
2.85729861
В каком смысле не работает?
Сообщение от Bretbas
1
C++
1
2
3
4
bool isEqual( float x, float y )
 {
     return std :: fabs( x - y ) < std::numeric_limits<float>::epsilon();
 }
Вообще-то std::numeric_limits<float>::epsilon() - это по стандарту расстояние между соседними числами float в районе единицы в данной реализации. В районе числа a оно будет равно epsilon * abs(a).
Сообщение от Bretbas
epsilon() слишком маленькое? Можно увеличить?
Жжете!
Вопрос: Необходимо введенные с клавиатуры 3 числа расположить в порядке возрастания или убывания

Помогите пожалуйста с задачей.
Есть три числа вводимые с клавиатуры, необходимо эти числа расположить в порядке возрастания или убывания, не важно. Я написал код, который находит только макс из трех чисел, как найти мин и средней? Помогите пожалуйста. Надо сделать с помощью ассемблерной вставки.
Код C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <conio.h>
 
using namespace std;
int main ()
{
    int x,y,q, max, min;
    cout<<"Vvedite x" <<endl;
    cin>>x;
    cout<<"Vvedite y" <<endl;
    cin>>y;
    cout<<"Vvedite q" <<endl;
    cin>>q;
_asm
{
        mov eax, x
        cmp y, eax
        jb h
        ja g
h:
    {
        cmp q, eax
        ja k
        mov max, eax
        jmp t
    }
g:
    {
        mov eax, y
        cmp q, eax
        ja k
        mov max, eax
        jmp t
    }
k:  
    {
        mov eax, q
        mov max, eax
        jmp t 
    }
t:
    
}
            cout<<"Z = "<<max<<endl;
            system ("pause");
 
}
Ответ: Если первое больше второго, то поменять их местами.
Если второе больше третьего, то поменять их местами.
Если первое больше второго, то поменять их местами.
Все.

И еще. Если ты вводишь переменные int , т.е знаковые, то сравнивать их правильнее не ja jb , а jg jl
ja jb - это для беззнаковых чисел.

Добавлено через 1 минуту
P.S.
Если использовать ja jb , то -1 > 0 , поскольку -1 считается как беззнаковое 4294967295
а если jg jl , то -1 < 0
Вопрос: Нахождение наибольшего однобайтового числа, расположенного в памяти, начиная с адреса 08FFН по 0905Н

Задача:
Написать программу нахождения наибольшего однобайтового числа, расположенного в памяти, начиная с адреса 08FFН по 0905Н.

Код ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
org 800
mvi d, 7
lxi h, 8ff
mov b, m
 
loop:
mov a, m
cmp b
jm skip
mov b, a
skip:
inx h
dcr d
jnz loop
hlt
В ячейки забиваем:
03 02 01 05 84 13 25
соответственно нашим адресам.
Результат является число 84, что в переводе в DEC = -124.
Помогите!!! Где ошибка в коде?
Ответ: У процессора 8080 есть в слове состояния флаг переноса, но нет флага переполнения.
Следовательно, беззнаковые числа в нем сравнивать легко, а вот знаковые не такое просто дело.

Добавлено через 1 минуту
Смоделируем ситуацию на персоналке. Вот если запустить такую программу
Код ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    Model   Tiny
    .Code
    Org 100h
Start:
    mov dx, offset TextNet
 
    xor cx, cx
testing:
    mov ah, 0
                cmp cl, ch
                jl  @
    mov ah, 1
@:  mov al, 0
                cmp cl, ch
                rcr bl, 1
                xor bl, cl
                xor bl, ch
                js  @@
    mov al, 1
@@: cmp al, ah
    jne Print
    loop    testing
 
    mov dx, offset TextDa
 
Print:  mov ah, 9
    int 21h
    ret
 
TextDa  db  'Vse verno$'
TextNet db  'Ne verno$'
 
    End Start
, то она выдаст Vse verno. А в ней я перебрал все возможные сочетания двух байт.

Добавлено через 38 секунд
Следовательно имеем эквивалент для сравнения знаковых без использования флага переполнения.

Добавлено через 1 минуту
У персоналки вот это
Код ASM
1
2
    cmp cl, ch
    jl  @
можно заменить на вот это
Код ASM
1
2
3
4
5
    cmp cl, ch
    rcr al, 1
    xor al, cl
    xor al, ch
    js  @@
Вот в таком духе тебе и надо сравнивать знаковые в своей программе.

Добавлено через 4 минуты
Т.е. логика к примеру такая. Если знаки сравниваемых чисел одинаковые, то сравнение должно быть
Код ASM
1
2
3
mov a, m
cmp b
jc skip
а если разные, то наоборот
Код ASM
1
2
3
mov a, m
cmp b
jnc skip
Добавлено через 7 минут
Плохо то, что я ассемблера 8080 почти не знаю. Хотя знаю ассемблеров
разных процессоров ... Но вроде-бы так :
Код ASM
1
2
3
4
5
6
    MOV A,M
    CMP B
    RAR
    XRA M
    XRA B
    JM skip