/ Forside / Teknologi / Udvikling / Perl / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Perl
#NavnPoint
bjarneA 141
poul_from 50
soccer 30
Nicknack 14
Tmpj 0
afrunding af decimal tal
Fra : news.cybercity.dk


Dato : 21-04-01 08:56

Hej

Jeg vil gerne afriunde en variabel så den kun har en decimal. Pleace
advice..

Mvh. Kasper



 
 
Peter J. Acklam (21-04-2001)
Kommentar
Fra : Peter J. Acklam


Dato : 21-04-01 09:38

"news.cybercity.dk" <baas@post1.tele.dk> writes:

> Jeg vil gerne afriunde en variabel så den kun har en
> decimal. Pleace advice..

$x = sprintf '%.1f', $x;

Peter

--
#!/local/bin/perl5 -wp -*- mode: cperl; coding: iso-8859-1; -*-
# matlab comment stripper (strips comments from Matlab m-files)
s/^((?:(?:[])}\w.]'+|[^'%])+|'[^'\n]*(?:''[^'\n]*)*')*).*/$1/x;

Lars Kim Lund (21-04-2001)
Kommentar
Fra : Lars Kim Lund


Dato : 21-04-01 10:13

Hej "news.cybercity.dk" <baas@post1.tele.dk>

>Jeg vil gerne afriunde en variabel så den kun har en decimal. Pleace
>advice..

perldoc -f sprintf

--
Lars Kim Lund
http://www.net-faq.dk/

Stig H. Jacobsen (21-04-2001)
Kommentar
Fra : Stig H. Jacobsen


Dato : 21-04-01 22:11

On Sat, 21 Apr 2001 09:56:17 +0200, news.cybercity.dk wrote:

> Jeg vil gerne afriunde en variabel så den kun har en decimal. Pleace
> advice..

Samme teknik kan bruges i alle sprog - her er Perl-udgaven:

$i = 2.34567;
$i = int($i * 10) / 10;

sprintf() er overkill her (og langsom).

--
Stig

Lars Balker Rasmusse~ (21-04-2001)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 21-04-01 22:21

"Stig H. Jacobsen" <nzaa7en001@sneakemail.com> writes:
> On Sat, 21 Apr 2001 09:56:17 +0200, news.cybercity.dk wrote:
> > Jeg vil gerne afriunde en variabel så den kun har en decimal. Pleace
> > advice..
>
> $i = int($i * 10) / 10;
>
> sprintf() er overkill her (og langsom).

Du har så vidt jeg husker ingen garanti for at $i kun har et decimal
efter ovenstående.

Derudover er det ikke en afrunding, men en afklipning af decimaler.
Hvis det er til udskrivning går det også galt hvis $i runder af til et
heltal.
--
Lars Balker Rasmussen "Woo hoo!?"

Stig H. Jacobsen (22-04-2001)
Kommentar
Fra : Stig H. Jacobsen


Dato : 22-04-01 18:55

On 21 Apr 2001 23:21:06 +0200, Lars Balker Rasmussen wrote:

>> $i = int($i * 10) / 10;
> Du har så vidt jeg husker ingen garanti for at $i kun har et decimal
> efter ovenstående.

Den må du gerne forklare mig? (der er max. et decimal hvis det er
det du mener).

> Derudover er det ikke en afrunding, men en afklipning af decimaler.

Nåja, korrekt.

> Hvis det er til udskrivning går det også galt hvis $i runder af til et
> heltal.

Det sagde spørgeren ikke noget om. (Der kan heller ikke udregnes
primtal, for det blev der heller ikke spurgt om).

--
Stig

Lars Balker Rasmusse~ (22-04-2001)
Kommentar
Fra : Lars Balker Rasmusse~


Dato : 22-04-01 19:18

"Stig H. Jacobsen" <nzaa7en001@sneakemail.com> writes:
> On 21 Apr 2001 23:21:06 +0200, Lars Balker Rasmussen wrote:
> >> $i = int($i * 10) / 10;
> > Du har så vidt jeg husker ingen garanti for at $i kun har et decimal
> > efter ovenstående.
>
> Den må du gerne forklare mig? (der er max. et decimal hvis det er
> det du mener).

IEEE "flydende komma" tal kan (igen, så vidt jeg husker) ikke garantere
at de indeholder bestemte decimal-brøker. 1.05 kan altså sagtens være
1.04999999996 når du prøver at printe det ud.

(En eller anden ret mig hvis jeg vrøvler).

> > Hvis det er til udskrivning går det også galt hvis $i runder af til et
> > heltal.
>
> Det sagde spørgeren ikke noget om. (Der kan heller ikke udregnes
> primtal, for det blev der heller ikke spurgt om).

Useriøst. Hvis spørgeren ikke nævner om tallet skal bruges til
beregning eller udskrivning, vælger man da den løsning der virker begge
steder.
--
Lars Balker Rasmussen "Special is bad."

Peter J. Acklam (22-04-2001)
Kommentar
Fra : Peter J. Acklam


Dato : 22-04-01 09:30

"Stig H. Jacobsen" <nzaa7en001@sneakemail.com> writes:

> On Sat, 21 Apr 2001 09:56:17 +0200, news.cybercity.dk wrote:
>
> > Jeg vil gerne afriunde en variabel så den kun har en
> > decimal. Pleace advice..
>
> Samme teknik kan bruges i alle sprog - her er Perl-udgaven:
>
> $i = 2.34567;
> $i = int($i * 10) / 10;

Dette er _ikke_ avrunding. Dette er trunkering.

> sprintf() er overkill her (og langsom).

Vel, sprintf() gjøre i alle fall avrunding. For en
int()-løsning, kan man bruke

$x *= 10;
$x = int $x + ( $x > 0 ? 0.5 : -0.5 ); # avrunding av heltall
$x /= 10;

Peter

--
#!/local/bin/perl5 -wp -*- mode: cperl; coding: iso-8859-1; -*-
# matlab comment stripper (strips comments from Matlab m-files)
s/^((?:(?:[])}\w.]'+|[^'%])+|'[^'\n]*(?:''[^'\n]*)*')*).*/$1/x;

Trond Michelsen (22-04-2001)
Kommentar
Fra : Trond Michelsen


Dato : 22-04-01 20:26


Stig H. Jacobsen <nzaa7en001@sneakemail.com> skrev i
meldingsnyheter:987887488.251343@dax.goth.dk...
>> Jeg vil gerne afriunde en variabel så den kun har en decimal. Pleace
>> advice..

> sprintf() er overkill her (og langsom).

"Premature micro-optimization is the root of all evil."

#!/usr/bin/perl
use Benchmark;

timethese (5_000_000, {
int => q{my $i = int(2.34567 * 10)/10},
sprintf => q{my $i = sprintf "%.1f", 2.34567},
});
__END__
Benchmark: timing 5000000 iterations of int, sprintf...
int: 6 wallclock secs ( 5.84 usr + 0.01 sys = 5.85 CPU)
@ 854700.85/s (n=5000000)
sprintf: 7 wallclock secs ( 6.75 usr + 0.00 sys = 6.75 CPU)
@ 740740.74/s (n=5000000)


sprintf() er ikke så langsom som du tror. Du sparer ca. 0,000000182 sekunder
på din metode fremfor å bruke sprintf(). I tillegg gir den altså galt svar.

--
Trond Michelsen



Stig H. Jacobsen (22-04-2001)
Kommentar
Fra : Stig H. Jacobsen


Dato : 22-04-01 20:54

On Sun, 22 Apr 2001 19:25:57 GMT, Trond Michelsen wrote:

> "Premature micro-optimization is the root of all evil."

Det samme kan siges om flueknepperi.

> sprintf() er ikke så langsom som du tror. Du sparer ca.
> 0,000000182 sekunder på din metode fremfor å bruke sprintf(). I
> tillegg gir den altså galt svar.

Jeg må nok tilstå, at min udtalelse nærmere var baseret på C og
de implementationer af sprintf(), som jeg har set.

Din måling overrasker mig, men nærmere implementation af de to
statements i Perl interesserer mig desværre ikke nok til, at jeg
kan eller vil bruge tid på at kommentere din indsats.

Jeg hopper af tråden.

--
Stig

Thorbjørn Ravn Ander~ (23-04-2001)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 23-04-01 21:31

"Stig H. Jacobsen" wrote:

> Jeg hopper af tråden.

Det er da ellers netop først når der bliver _målt_ at det giver mening
at snakke om optimering. Hop på igen - Benchmark er et fantastisk
værktøj (kombineret med Perl profilering som kun virker under Unix) til
at blive klogere af.

Herudover er det den eneste måde til at afgøre hvem der har ret, når man
først er gået i skyttegravene.

--
Thorbjørn Ravn Andersen "...plus... Tubular Bells!"
http://bigfoot.com/~thunderbear

Trond Michelsen (23-04-2001)
Kommentar
Fra : Trond Michelsen


Dato : 23-04-01 22:59

Thorbjørn Ravn Andersen <thunderbear@bigfoot.com> skrev i
meldingsnyheter:3AE490E8.9D52DADE@bigfoot.com...
> "Stig H. Jacobsen" wrote:
>> Jeg hopper af tråden.
> Det er da ellers netop først når der bliver _målt_ at det giver mening
> at snakke om optimering. Hop på igen - Benchmark er et fantastisk

*host* Dessverre er det slik at det er lett å glemme seg bort, og benchmarke
noe som optimizes bort av kompileren :( *blush*

Ny benchmark følger...

#!/usr/bin/perl
use Benchmark;

my $num = 2.34567;
timethese (1_000_000, {
var_int => q{my $i = int($num * 10)/10},
var_sprintf => q{my $i = sprintf "%.1f", $num},
const_int => q{my $i = int(2.34567 * 10)/10},
const_sprintf => q{my $i = sprintf "%.1f", 2.34567},
});
__END__
Benchmark: timing 1000000 iterations of const_int, const_sprintf, var_int,
var_sprintf...
const_int: 1 wallclock secs ( 1.18 usr + 0.00 sys = 1.18 CPU)
const_sprintf: 1 wallclock secs ( 1.35 usr + 0.00 sys = 1.35 CPU)
var_int: 4 wallclock secs ( 3.59 usr + 0.00 sys = 3.59 CPU)
var_sprintf: 23 wallclock secs (23.01 usr + 0.00 sys = 23.01 CPU)

Stig har derfor helt rett i at sprintf() er tregere enn hans metode - nesten
seks ganger tregere, faktisk.

Men - det utgjør allikevel ikke mer enn 0,00002 sekunder pr. avrunding, og
med mindre du utfører fryktelig mange avrundinger i et program, så er
performance et ugyldig argument for å unngå sprintf().

Det viktigste bør være at koden gir riktig resultat, deretter er det viktig
at koden er lett å lese.

> værktøj (kombineret med Perl profilering som kun virker under Unix) til
> at blive klogere af.

Nettopp. Det er bl.a. annet det som menes med at "_premature_
micro-optimixing is the root of all evil". Man skal *ALDRI* foreta
mikro-optimalisering av kode før man er *HELT* sikker på at man kan oppnå
noe med det. En profilering vil avsløre hvilke subrutiner som kalles oftest,
og hvilke subrutiner som bruker mest CPU-tid i løpet av programmets levetid.
Det er bortkastet tid å optimalisere en subrutine så den blir dobbelt så
rask, dersom dette bare kutter eksekveringstiden til programmet med et
tiendels sekund. Spesielt dersom du kan kutte eksekveringstiden med 5
sekunder på å gjøre en annen subrutine 10% raskere.

> Herudover er det den eneste måde til at afgøre hvem der har ret, når man
> først er gået i skyttegravene.

( bare man er enige om at benchmarken er riktig utført

--
Trond Michelsen




Thorbjørn Ravn Ander~ (24-04-2001)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 24-04-01 06:17

Trond Michelsen wrote:

> ( bare man er enige om at benchmarken er riktig utført

Det fortalte mig da at Perl flytter konstante beregninger uden for
løkker - så lærte jeg ogå noget i dag

Mht optimering, så tror jeg Perl er et oplagt eksempel på at man skal
lade være førend man er sikker. Perl er helt fantastisk til at skrive
ulæselig kode i (C gå hjem) og netop paradigmet med at man kan sige ting
på flere måder afhængigt af hvad der er vigtigt, kan gøre det
fuldstændig uforståeligt. Hvis det tager en dag at forstå noget gammel
kode istedet for 5 minutter, så er al optimering og lignende tabt på
gulvet i pengemæssige henseende. Hvis man optimerer på noget som kunne
"fikses" ved at købe en spritny server, så skal gevinsten godt nok være
stor.

Perl profileren er god at kende til det formål.


--
Thorbjørn Ravn Andersen "...plus... Tubular Bells!"
http://bigfoot.com/~thunderbear

Thorbjørn Ravn Ander~ (23-04-2001)
Kommentar
Fra : Thorbjørn Ravn Ander~


Dato : 23-04-01 21:28

"Stig H. Jacobsen" wrote:
>
> On Sat, 21 Apr 2001 09:56:17 +0200, news.cybercity.dk wrote:
>
> > Jeg vil gerne afriunde en variabel så den kun har en decimal. Pleace
> > advice..
>
> Samme teknik kan bruges i alle sprog - her er Perl-udgaven:
>
> $i = 2.34567;
> $i = int($i * 10) / 10;
>
> sprintf() er overkill her (og langsom).

Du er ikke garanteret at resultatet ikke bliver noget med
10.19999999999, da 10 ikke er en endelig brøk i 2-talssystemet.
sprintf-udgaven returnerer en streng uden dikkedarer.

--
Thorbjørn Ravn Andersen "...plus... Tubular Bells!"
http://bigfoot.com/~thunderbear

Søg
Reklame
Statistik
Spørgsmål : 177559
Tips : 31968
Nyheder : 719565
Indlæg : 6408938
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste