К списку форумов К списку тем
Регистрация    Правила    Главная форума    Поиск   
Имя: Пароль:
Рекомендовать в новости

if x = 0 then res := 0 else res := 1 -> как?

Гость
0 - 31.07.2012 - 19:24
Дано целое положительное число X от 0 n. Существует ли такая операция (функция и т.д.), результатом которой будет 0, если X=0 и 1, если X > 0? Что-то не придумаю.


Гость
1 - 31.07.2012 - 19:38
http://en.wikipedia.org/wiki/Sign_function
Гость
2 - 31.07.2012 - 19:40
в языках программирования оноже http://docs.oracle.com/javase/6/docs...um%28double%29
Гость
3 - 31.07.2012 - 20:06
Ну так определи себе функцию и используй ее. Делов-то на три минуты. К своему стыду и смеху, я как-то обнаружил, что почти треть функций модуля SysUtils у меня собственные - зато я не зависел от багов, которые там повставляли индусы от Borland, а только от своих собственных.
Гость
4 - 31.07.2012 - 20:16
sign так же и работает. хочу без оператора условного перехода, либо доказать, что это невозможно. чота ума не хватает.
Гость
5 - 31.07.2012 - 20:18
т.е. нужно решить задачу математически, а не алгоритмически. первое что пришло на ум - x в степени x, но я забыл школьные уроки алгебры - оказалось, что не прокатит.
Гость
6 - 31.07.2012 - 20:37
Один вопрос, а зачем тебе такая функция? Чем тебе переход не нравится?

Не хочешь переход можешь использовать сдвиги и or
или
можешь использовать деление самого на себя и ловить exception при делении на ноль, правда та будет дофига переходов вставленных компилятором ;)

А вообще от чего так торкает ;)
Гость
7 - 31.07.2012 - 20:41
exception суть тот же переход. сдвиги и т.п. это тоже алгоритмы, а я хочу математику. из спортивного интереса. типа как поменть a и b местами без третей переменой. дано число, к нему можно применить любые арифметические и функциональные преобразования - и больше никак. неужели нет решения? : )
Гость
8 - 31.07.2012 - 20:49
при условии что всегда X >=0

var
x:Byte;
y:Byte;
begin
x:=100;
y:=ord(x >0);
x:=0;
y:=ord(x >0);
end;

Unit1.pas.30: x:=100;
00452168 C645FB64 mov byte ptr [ebp-$05],$64
Unit1.pas.31: y:=ord(x >0);
0045216C 807DFB00 cmp byte ptr [ebp-$05],$00
00452170 0F97C0 setnbe al
00452173 8845FA mov [ebp-$06],al
Unit1.pas.32: x:=0;
00452176 C645FB00 mov byte ptr [ebp-$05],$00
Unit1.pas.33: y:=ord(x >0);
0045217A 807DFB00 cmp byte ptr [ebp-$05],$00
0045217E 0F97C0 setnbe al
00452181 8845FA mov [ebp-$06],al
Unit1.pas.35: end;

Переходов нет ;)
Гость
9 - 31.07.2012 - 21:05
незнаю на бэйсине решается все очень просто

Dim a As Boolean
Dim x As Variant
x = 255
a = x
Гость
10 - 31.07.2012 - 21:06
я так понимаю тут используется порядковый номер false (0) и true (1). это работает, но не честно (зависит от реализации? или я не совсем понял)
Гость
11 - 31.07.2012 - 21:08
(9) и (8) аналогичны. tcode привел элегантный хак : ) однако это хак.
Гость
12 - 31.07.2012 - 21:23
5-Rat >

там в википедии написано про элементарные функции и способы представления
Гость
13 - 31.07.2012 - 21:30
если задача спортивная и хренение числа, например байт, то както так (на жаве)

(-i&128)/128

только работать будет от 0 до 128
Гость
14 - 31.07.2012 - 22:04
Ну это все однотипные решения. Да, они работают, будем считать, что задача решена наполовину. Надо думать над математическим способом. В идеале - получить выражение полиномиального вида.
Гость
15 - 31.07.2012 - 22:23
14-Rat >

емнип кусочно заданную функцию через полином не выразить.
Гость
16 - 31.07.2012 - 22:44
13->wayerr > (-i&128)/128

я идиот, просто, без деления

((-i) >> 8) & 1
17 - 31.07.2012 - 23:06
а может что-то с cos(2"пи"*x) замутить?
18 - 31.07.2012 - 23:09
ой, только не 2 пи, а пи/2
ну и типа по модулю взять
Гость
19 - 01.08.2012 - 01:26
to0 Вообще есть такая книжка: Генри Уоррен "Алгоритмические трюки для программистов" вот в ней подобные вещи и рассматриваются.
например: для функции sign там приводят следующую реализацию
-(x >> 31)|(-x >> 31)

на Delphi это будет выглядеть так
var
d:integer;
y:integer;
begin
d:=-1000;
y:=-(d shr 31) or (-d shr 31);
d:=0;
y:=(-(d shr 31)) or (-d shr 31);
end;
Гость
20 - 01.08.2012 - 01:34
ps но мне мой вариант нравиться больше, так как он занимает всего две машинные команды cmp и setnbe

Да в книжке есть еще вариант короче для знакового сдвига - там будет не 5 действий, а 4. Вообще там много подобных решений и есть такие что без пол-литра не поймешь. Я бы предпочел в 98% использовать более простое и понятное решение чем то что приведено в этой книге, пусть даже оно бы и медленней работало;)
Гость
21 - 01.08.2012 - 01:53
pps для случая положительных чисел, для хранения которых используется тип со знаком формулу можно еще упростить до
-x >> 31
Гость
22 - 01.08.2012 - 11:05
(17) Логичнее не cos, а sin, но фнукция периодическая, придется еще доказать, что при любом X она не обратися в 0, кроме когда X = 0. А так да, для любого натурального X подойдет abs(sin(x)), я об этом уже думал, в принципе должно работать в 99,999% случаев.
23 - 01.08.2012 - 11:45
22-Rat > насчет синуса согласна, уже просто туплю и путаю его с косинусом, а рыться в поисках истины некайф:)
Но причем тут
Цитата:
Сообщение от Rat Посмотреть сообщение
придется еще доказать, что при любом X она не обратися в 0, кроме когда X = 0.
Приведи еще пример, при каком х она обратится в 0, если у нее все аргументы будут кратны пи/2, ее значение может быть или 1, или -1.
Гость
24 - 01.08.2012 - 13:35
при том что sin(x) = 0 при x кратному pi, в том числе при x=0. ход конем в том, что константа pi - сильно не целая, и врядли когда x кратно pi для натуральных x, кроме 0. но это, строго говоря, не очевидно.
Гость
25 - 01.08.2012 - 13:47
проверил sin(x) для x=1..2147483647 - нет нулей. для 32-битных чисел с знаком, таким образом, способ работает. будет ли более элегантные варианты?
Гость
26 - 01.08.2012 - 13:49
т.е. рабочий вариант будет примерно такой: trunc(sin(x) + 1 - 0.00000000000001)
Гость
27 - 01.08.2012 - 14:18
to 26 а как же условие без прыжков.
у тебя же как минимум вызов двух функция и соответственно будут и call и ret.
Гость
28 - 01.08.2012 - 14:20
опечатка
функция - читать как функций
Гость
29 - 01.08.2012 - 16:25
про безусловные переходы я ничего не говорил : )
кстати + к26, надо синус еще в abs взять.
Гость
30 - 03.08.2012 - 15:28
res = CInt(Abs(CBool(x)))
Гость
31 - 04.08.2012 - 01:10
to30 расслабься автора уже давно отпустило и больше так не торкает ;)
Даже слабо представляю где он свое решение будет использовать. Одно дело, если бы он так пытался оптимизировать некий кусок процедуры, что вызывает дофига раз и сильно сказывается на производительности. И вот он запустил какой нибудь очень дорогой профилировщик и вооружившись книжкой касперского по технике оптимизации использования памяти пытался избавиться от лишнего условного перехода, разворачивал циклы, выравнивал данные в памяти и.т.п. Но здесь этим даже не пахнет.


К списку вопросов
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск




Copyright ©, Все права защищены