Autor Beitrag
Heiko
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Fr 13.05.05 20:18 
Gibt es ein Power das nur Integer (Byte reicht auch) erwartet und Integer zurückgibt?
Ich will immer 2^0, ..., 2^7 berechnet haben, will aber das Ergbnis nicht runden. IntPower ist leider das gleiche wie Power, macht also nicht was der Name sagt.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 13.05.05 20:20 
Jo: 1 shl Exponent (= 2^Exponent)

IntPower ist nicht dasselbe wie Power. IntPower ist für ganzzahlige (d.h. auch negative) Exponenten.
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 13.05.05 20:39 
ansonsten:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function hoch(base,exp:integer):int64;
// (c) retasmtools
var i : integer;
begin
    result := 1;
    for i := 1 to exp do result := result * base;
end;

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 13.05.05 21:01 
Etwas Off-Topic aber trotzdem: Bei user profile iconretnyg's Prozedur wird die Basis exp-mal zu 1 multipliziert. Eine solche Iteration ist vor allem für grössere Exponenten (bei mir aber schon ab sehr kleinen wie 4) langsamer als IntPower+Runden.
Dafür ist die Genauigkeit bei seiner Methode (mit Int64 gerechnet) garantiert.

PS:
Etwas praxisfern, aber theoretisch könnte man zuerst die Primfaktorenzerlegung von exp vornehmen und über diese Zahlen iterieren.
Beispiel 3^18 => statt 3*3*3*3*3*3*... 18-mal auszuführen, könnte man einfach ((3^3)^3)^2 rechnen. Aber okay. Bis man die Zahl faktorisiert hätte, ginge es wohl länger ;)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 13.05.05 21:59 
Schneller geht es über die Binär-Darstellung vom Exponenten:

Exp = 0 --> 1
Exp = 1 --> Basis
Exp and 1 = 0 --> Power(Basis, Exp shr 1);
Exp and 1 = 1 --> Power(Basis, Exp shr 1) * Basis;

Sonderfälle:
0^0 --> Exception
Basis = 0, Exp <> 0 --> 0;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
raziel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2453

Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
BeitragVerfasst: Fr 13.05.05 22:05 
user profile iconBenBE hat folgendes geschrieben:
0^0 --> Exception

Wieso das? 0^0 = 1

_________________
JSXGraph
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 13.05.05 22:15 
user profile iconraziel hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
0^0 --> Exception

Wieso das? 0^0 = 1

Nein, weil dann folgende Bedingung gelten müsste:

ausblenden Quelltext
1:
lim(Basis^0, Basis --> 0) = lim(0^Exp, Exp --> 0)					

Diese kann aber nicht gelten, da 0^Exp nicht stetig über dem Definitionsbereich abgeleitet werden kann.

Außerdem gibt es noch genug andere Widersprüche dieser Definition.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 13.05.05 22:16 
@BenBE:
Du meinst sowas: (?)
3^18 => 3^(16+2) => 3^16*3^2 => Power(3,16)*Power(3,2)

Das ergibt 16+2 = 18 Multiplikationen.
Für ((3^3)^3)^2 sind aber nur 8 Multiplikationen nötig. Bzw. wenn du schon Power aufrufst, dann nur einmal, um gleich das Schlussresultat zu erhalten (=> 1 x exp und 1 x ln).

Oder hab ich was falsch verstanden?

@raziel:
lim 0^x = 0
x->0
Aber:
lim x^0 = 1
x->0

(Jedoch gibt es tatsächlich Taschenrechner, die für 0^0 einfach 1 rausspucken.)

//Edit: BenBE war schneller ;O
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 13.05.05 22:27 
user profile icondelfiphan hat folgendes geschrieben:
@BenBE:
Du meinst sowas: (?)
3^18 => 3^(16+2) => 3^16*3^2 => Power(3,16)*Power(3,2)

Nicht ganz:
3^18 => (3^9)^2 => ((3^4)^2 * 3)^2 => (((3^2)^2)^2 * 3)^2

Das sind zwar ein paar mehr Multiplikationen (für kleine Zahlen), aber es entfällt der Aufwand für's Faktorisieren.

Außerdem wird diese Methode auch häufig zum Potenzieren Modulo genutz (z.B. bei Rabbin-Miller und RSA).

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 13.05.05 22:39 
user profile iconBenBE hat folgendes geschrieben:
Schneller geht es über die Binär-Darstellung vom Exponenten:

Exp = 0 --> 1
Exp = 1 --> Basis
Exp and 1 = 0 --> Power(Basis, Exp shr 1);
Exp and 1 = 1 --> Power(Basis, Exp shr 1) * Basis;

Sonderfälle:
0^0 --> Exception
Basis = 0, Exp <> 0 --> 0;

könntest du das in ne delphi funktion verpacken ?

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 13.05.05 22:57 
user profile iconretnyg hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
Schneller geht es über die Binär-Darstellung vom Exponenten:

Exp = 0 --> 1
Exp = 1 --> Basis
Exp and 1 = 0 --> Power(Basis, Exp shr 1);
Exp and 1 = 1 --> Power(Basis, Exp shr 1) * Basis;

Sonderfälle:
0^0 --> Exception
Basis = 0, Exp <> 0 --> 0;

könntest du das in ne delphi funktion verpacken ?


ausblenden volle Höhe Delphi-Quelltext
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:
Procedure FastPower(B, E: Integer): Int64;
begin
    If B = 0 Then
    Begin
        If E = 0 Then Raise EInvalidOperation.Create('Calculating 0^0.');
        Result := 0;
        Exit;
    end;

    If E = 0 Then
    Begin
        Result := 1;
        Exit;
    end
    else if E = 1 Then
    Begin
        Result := B;
        Exit;
    end
    else if E and 1 = 0 Then
    Begin
        Result := FastPower(B, E shr 1);
        Result := Sqr(Result);
        Exit;
    end
    else 
    Begin
        Result := FastPower(B, E shr 1);
        Result := Sqr(Result) * B;
        Exit;
    end;
end;


Für E >= 0!!!

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 14.05.05 09:37 
user profile icondelfiphan hat folgendes geschrieben:
IntPower ist nicht dasselbe wie Power. IntPower ist für ganzzahlige (d.h. auch negative) Exponenten.


Aber keine vollständiger Power mit Integer. Der Exponent ist nur ein Integer. Ich will aber Base, Exponent und Result als Integer (oder Byte).

Aso und ihr habt ja auch ein paar andere Vorschläge gemacht, die ich leider nicht richtig gebrauchen kann, da ich jedes 8. mal 2^0 brauche. Ich werde es jetzt wohl anders Regeln

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure IntegerPowerOfTwo(Exponent: Byte);
begin
 case Exponent of
  0: Result:=1;
  1: Result:=2;
  2: Result:=4;
  3: Result:=8;
  4: Result:=16;
  5: Result:=32;
  6: Result:=64;
  7: Result:=128;
end;


Ich hatte eigentlich keine Lust so eine Prozedur mit einzubauen, weshalb ich es mit Power machen wollte. Aber ich glaube bald, dass die Variante am schnellsten sein wird, da ich ja weiß welche Exponenten und Basen ich immer habe, wodurch ich schon das Ergebnis in den Quellcode reinimplementieren kann. Die Variante mit round (oder Trunc) wird sicherlich nicht schneller sein.

Trotzdem thx für die Antworten. Wenn es bessere Varianten gibt bin ich immer noch offen :wink: .
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 14.05.05 11:12 
user profile iconHeiko: Du hast den ersten Teil meines ersten Beitrags einfach ignoriert :?

1 shl Exponent ist die Lösung.

(1 shl 0) = 1
(1 shl 1) = 2
(1 shl 2) = 4
(1 shl 3) = 8
(1 shl 4) = 16
...

(Die Bemerkung ist jetzt zwar überflüssig, trotzdem: Statt ein solches Case wäre es wohl geschickter, eine konstante array zu definieren)
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 14.05.05 12:05 
sry. Ich hatte ihn nicht ignoriert, aber vergessen, da ich die anderen gelesen noch hatte.

thx delfiphan für deine Erinnerung :wink: .
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Sa 14.05.05 13:52 
user profile iconHeiko hat folgendes geschrieben:

ausblenden Delphi-Quelltext
1:
procedure IntegerPowerOfTwo(Exponent: Byte);					
Wenn es bessere Varianten gibt bin ich immer noch offen

wenn du deine prozeduren schnell machen willst, solltest du keine anderen variablentypen als 32bittige verwenden, da der prozessor sonst immer erst konvertieren muss

meine bruteforce-passwort generator prozedur wurde alleine durch umstellen einiger variablen von byte auf dword um gut 20% schneller

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
Heiko Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Sa 14.05.05 17:42 
Ich brauche das immer als Byte, da ich immer Byteweise bei meinem Packprogramm schreibe :wink: , ansonsten nehem ich auch immer Integer oder Cardinal.