Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 28 мар 2024, 19:20

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 72 ]  На страницу Пред.  1 ... 3, 4, 5, 6, 7, 8  След.
Автор Сообщение
СообщениеДобавлено: 29 авг 2013, 16:46 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Поэтому другое предложение. Определим новую операцию в SYSTEM.h (ну и в Ofront'е конечно тоже) — беззнаковое деление __UDIV, которое будет принимать любые аргументы, но делать вид, что их типы — беззнаковые. Задать реализацию этой операции мы сможем в SYSTEM.h (для Z80 — хоть вызовом асмовой процедуры деления, а хоть прямой генерацией inline-кода простого вычитания в цикле). ...
#define __UDIV(a, b) (((unsigned)a) / ((unsigned)b)) /* Допустим, пока так. */
Верно ли я понял, что "(unsigned)a" - это "(unsigned int)a" независимо от типа этого а. А для короткого и длинного надо писать тоже конкретно "(unsigned short)a" и "(unsigned long)a"?
Можно ли в С как-то написать универсальное приведение к беззнаковому "(unsigned ???)a" , где компилятор сам подставит ??? чтобы длина целого не менялась?
А если нет, то как нам организовать динамическое беззнаковое деление? Завести #define __UDIVint(a, b), #define __UDIVshort(a, b) и #define __UDIVlong(a, b) чтобы Ofront генерировал в создаваемую С-программу конкретную операцию беззнакового деления, в зависимости от типа переменной цикла?

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 02 сен 2013, 22:21 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Saferoll писал(а):
Верно ли я понял, что "(unsigned)a" - это "(unsigned int)a" независимо от типа этого а. А для короткого и длинного надо писать тоже конкретно "(unsigned short)a" и "(unsigned long)a"?

Мне всегда казалось, что unsigned — это приведение к беззнаковому с сохранением той же разрядности. Для проверки написал такой код:
Код: "C"
#include "SYSTEM.h"
#include "Console.h"
 
export main(int argc, char **argv)
{
signed char schar;
signed short int sint;
 
Console_WriteStr((CHAR*)"sizeof(signed char) = ", 0);
Console_WriteInt(sizeof(schar));
Console_WriteLn();
Console_WriteStr((CHAR*)"sizeof((unsigned)signed char) = ", 0);
Console_WriteInt(sizeof((unsigned)schar));
Console_WriteLn();
 
Console_WriteStr((CHAR*)"sizeof(signed short int) = ", 0);
Console_WriteInt(sizeof(sint));
Console_WriteLn();
Console_WriteStr((CHAR*)"sizeof((unsigned)signed short int) = ", 0);
Console_WriteInt(sizeof((unsigned)sint));
Console_WriteLn();
}
Результат оказался таким:

sizeof(signed char) = 1
sizeof((unsigned)signed char) = 4
sizeof(signed short int) = 2
sizeof((unsigned)signed short int) = 4

Значит да, обычный unsigned — это unsigned int (можно опускать int), а вовсе не то, что я думал. Приведение других типов надо описывать полностью, без упущений. Вобщем-то это не очень логично, как и много чего в Си.

Saferoll писал(а):
Можно ли в С как-то написать универсальное приведение к беззнаковому "(unsigned ???)a" , где компилятор сам подставит ??? чтобы длина целого не менялась?
Да, видимо, можно. Это будет хитрый макрос вида:
Код: "C"
#define UNI_UNSIGNED(i) ( sizeof(i)==1 ? (unsigned char)i : \
( sizeof(i)==2 ? (unsigned short int)i : \
( sizeof(i)==4 ? (unsigned int)i : \
(unsigned long)i )))
Я его потестил, но он не работает (всё равно возвращает размер 4 для всех типов). Надо консультироваться с опытными сишниками.

Saferoll писал(а):
А если нет, то как нам организовать динамическое беззнаковое деление? Завести #define __UDIVint(a, b), #define __UDIVshort(a, b) и #define __UDIVlong(a, b) чтобы Ofront генерировал в создаваемую С-программу конкретную операцию беззнакового деления, в зависимости от типа переменной цикла?
Гм, гм. Наверное это простое решение. Но вроде бы не очень элегантное, да? :) Задача поставлена, будем думать ещё.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 05 сен 2013, 08:45 
Не в сети

Сообщения: 203
Saferoll писал(а):
Верно ли я понял, что "(unsigned)a" - это "(unsigned int)a" независимо от типа этого а. А для короткого и длинного надо писать тоже конкретно "(unsigned short)a" и "(unsigned long)a"?

В сях тип unsigned является синонимом типа unsigned int. unsigned short и unsigned long -- это уже отдельные типы...

Saferoll писал(а):
Можно ли в С как-то написать универсальное приведение к беззнаковому "(unsigned ???)a" , где компилятор сам подставит ??? чтобы длина целого не менялась?


А зачем это надо?


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 05 сен 2013, 09:01 
Не в сети

Сообщения: 203
Zorko писал(а):
Saferoll писал(а):
Можно ли в С как-то написать универсальное приведение к беззнаковому "(unsigned ???)a" , где компилятор сам подставит ??? чтобы длина целого не менялась?
Да, видимо, можно. Это будет хитрый макрос вида:
Код: "C"
#define UNI_UNSIGNED(i) ( sizeof(i)==1 ? (unsigned char)i : \
( sizeof(i)==2 ? (unsigned short int)i : \
( sizeof(i)==4 ? (unsigned int)i : \
(unsigned long)i )))
Я его потестил, но он не работает (всё равно возвращает размер 4 для всех типов). Надо консультироваться с опытными сишниками.

Такой макрос не будет работать, так как тернарная операция ?: должна иметь одинаковый тип обоих выходных операндов, поэтому компилятор приводит все выражения к (unsigned long) как максимальному тут типу.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 05 сен 2013, 09:35 
Не в сети

Сообщения: 203
В С11 этот макрос мог бы выглядеть примерно так:
Код: "C"
#define UNI_UNSIGNED(i) _Generic((i),        \
long int: (unsigned long int), \
int: (unsigned int), \
short int: (unsigned short int), \
char: (unsigned char)) (i)


К сожалению, не могу поверить за отсутсвием компилятора С11 )))


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 05 сен 2013, 17:01 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Saferoll писал(а):
А если нет, то как нам организовать динамическое беззнаковое деление? Завести #define __UDIVint(a, b), #define __UDIVshort(a, b) и #define __UDIVlong(a, b) чтобы Ofront генерировал в создаваемую С-программу конкретную операцию беззнакового деления, в зависимости от типа переменной цикла?
Гм, гм. Наверное это простое решение. Но вроде бы не очень элегантное, да? :) Задача поставлена, будем думать ещё.
Ну раз в Си простого решения нет, то придется средствами Ofront. Думаю получится всяко элегантнее, чем какая-нибудь головоломная С-конструкция, которая к тому же не на всех компиляторах будет срабатывать.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 05 сен 2013, 17:04 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
geniepro писал(а):
Saferoll писал(а):
Можно ли в С как-то написать универсальное приведение к беззнаковому "(unsigned ???)a" , где компилятор сам подставит ??? чтобы длина целого не менялась?


А зачем это надо?
Думаю, действительно особой необходимости в этом нет. Заставлю Ofront генерировать операцию приведения конкретной разрядности, вроде это не так и трудно.

_________________
А кроме того, я думаю, что корFORген должен быть разрушен!


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 01 окт 2013, 23:17 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Олег, помнишь ту проблемку с LONGINT DIV?

Оказывается, история с этой ошибкой имеет продолжение. Ко мне обратился Гельмут Цинн с репортом об ошибке в моём патче, убирающем ограничение на размер кодовых процедур. По ходу разбирательства было выяснено, что тот патч ни при чём, а виноват недофикшенный LONGINT DIV. Вот что пишет Иван Денисов:
Иван Денисов писал(а):
Про LONG DIV надо применить!
Но не вот эту сокращенную правку, которую Louwe вам дал 29 мая:
Код: "OBERON"
  1. DevCPC486.FloatDOp
  2. ...
  3. | div:
  4. IF y.mode # Reg THEN LoadR(y); END;(* <<< add this line *)
  5. IF rev THEN Dev2CPL486.GenFDOp(FDIVR, y) ELSE Dev2CPL486.GenFDOp(FDIV, y) END;
  6. Floor(y,FALSE)
  7. ...
А полную! от 19-Dec-2011
у меня к сожалению нет оригинального письма. Не был тогда подписан.

Но там так должно быть:
Код: "OBERON"
  1. IF y.mode # Reg THEN LoadR(y); rev := ~rev END;

В Issue надо привести вот эту вами отловленную ошибку:

Код: "OBERON"
  1. (* BlackBox Component Builder 1.6-rc6 Windows XP *)
  2. MODULE LongintDIV;
  3.  
  4. TYPE
  5. Object = POINTER TO RECORD int: INTEGER END ;
  6. VAR
  7. u : Object;
  8. L : LONGINT;
  9. BEGIN
  10. NEW(u);
  11. u.int :=1;
  12. L := LONG(u.int) DIV u.int ; (* TRAP 0 is here *)
  13. (* If rewrite the code as L := LONG(u.int); L := L DIV u.int; then all compiles OK. *)
  14. END LongintDIV.
TRAP 0

DevCPC486.CheckAv [00000526H]
.reg INTEGER 0
DevCPC486.Floor [00002E20H]
.c DevCPL486.Item fields
.local INTEGER 2288212
.useSt1 BOOLEAN FALSE
.x DevCPL486.Item fields
DevCPC486.FloatDOp [00004708H]
.a DevCPL486.Item fields
.b DevCPL486.Item fields
.local INTEGER 0
.rev BOOLEAN FALSE
.subcl BYTE 3
.x DevCPL486.Item fields
.y DevCPL486.Item fields

И вот этот тест:
Код: "OBERON"
  1. MODULE Test;
  2.  
  3. IMPORT Log := StdLog;
  4.  
  5. PROCEDURE Do* ();
  6. VAR
  7. x: LONGINT;
  8. y: INTEGER;
  9. BEGIN
  10. x := 10; y := 2;
  11. Log.Int(x DIV y); Log.Ln;
  12. END Do;
  13.  
  14. END Test.
  15.  
  16. Q^ Test.Do
Так что фиксим бока неудачного патча новым коммитом. Без этого даже System.Strings собирается криво.


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 03 окт 2013, 17:13 
Не в сети
Администратор
Аватара пользователя

Сообщения: 273
Откуда: Россия
Zorko писал(а):
Олег, помнишь ту проблемку с LONGINT DIV?
Оказывается, история с этой ошибкой имеет продолжение
....
Так что фиксим бока неудачного патча новым коммитом. Без этого даже System.Strings собирается криво.
Вот чем и хорошо Open Source, что если один что-нибудь пропустит, так другой поправит. Что же, пофиксим фикс :)


Вернуться к началу
 Профиль  
Ответить с цитатой  
СообщениеДобавлено: 03 окт 2013, 19:11 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
В точку, Олежа! Open Source рулит. :)


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 72 ]  На страницу Пред.  1 ... 3, 4, 5, 6, 7, 8  След.

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club