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 > насчет синуса согласна, уже просто туплю и путаю его с косинусом, а рыться в поисках истины некайф:) Но причем тут Приведи еще пример, при каком х она обратится в 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 расслабься автора уже давно отпустило и больше так не торкает ;) Даже слабо представляю где он свое решение будет использовать. Одно дело, если бы он так пытался оптимизировать некий кусок процедуры, что вызывает дофига раз и сильно сказывается на производительности. И вот он запустил какой нибудь очень дорогой профилировщик и вооружившись книжкой касперского по технике оптимизации использования памяти пытался избавиться от лишнего условного перехода, разворачивал циклы, выравнивал данные в памяти и.т.п. Но здесь этим даже не пахнет. | |
![]() | Интернет-форум Краснодарского края и Краснодара |