Avatar billede mikoalngelo Nybegynder
14. februar 2004 - 17:44 Der er 47 kommentarer og
1 løsning

Primtals-generator giver fejl-output

Jeg har denne primtals-tjekker, men når jeg kører den, så siger den også, at f.eks. 22 er et primtal...
Prøv at bruge den efterfølgende for-løkke...

// Returnerer tværsummen af et tal
function tvaersum(tal){
    talAry = tal.toString().split('');
    var sum = 0;
    var gammelSum;
    var started = false;
    while(gammelSum > 9 || !started)
    {
        started = true;
        for (a = 0; a < talAry.length; a++)
        {
            sum += Number(talAry[a]);
        }
        talAry = sum.toString().split('');
        gammelSum = sum;
        sum = 0;
    }
    return gammelSum;
}

//Returnerer false hvis tal ikke er et primtal, og true hvis det er
function tjekPrimtal(tal)
{
    var to, tre, fem, syv, primtal = false;
    var sidsteTal = tal.toString().split('');
    sidsteTal = sidsteTal[sidsteTal.length-1];
   
    // Tjek om tallet er deleligt med 2
    switch (sidsteTal)
    {
        case 2: to = true;
        break;
        case 4: to = true;
        break;
        case 6: to = true;
        break;
        case 8: to = true;
        break;
        default: to = false;
    }   
   
    // Tjek om tallet er deleligt med 3
    switch (tvaersum(tal))
    {
        case 3: tre = true;
        break;
        case 6: tre = true;
        break;
        case 9: tre = true;
        break;
        default: tre = false;
    }
    // Tjek om tallet er deleligt med 5
    if (sidsteTal == 0 || sidsteTal == 5)
        fem = true;
    else
        fem = false;
       
    // Tjek om tallet er deleligt med 7
    if ((tal/7) == Math.round(tal/7))
        syv = true;
    else
        syv = false;
   
    if (to || tre || fem || syv)
        primtal = false;
    else
        primtal = true;
   
    //Undtagelser:
    if (tal == 2 || tal == 3 || tal == 5 || tal == 7)
        primtal = true;
    if (tal == 1)
        primtal = false;
   
    return primtal;
}



<script type="text/javascript">
for (b = 0; b <= 100; b++)
{
    if (tjekPrimtal(b))
        document.write(b + "<br>");
}
</script>



HJÆLP!!!-)

PS: Bare ret mig, hvis pointene er urimelige.
Avatar billede roenving Novice
14. februar 2004 - 18:00 #1
Det er da en besværlig måde du gør det på, denne virker:

<script type="text/javascript">
function primtalscheck(val){
val = +val;
if(val%2==0)return false;
for(i=3;Math.floor(Math.sqrt(val))>i;i+=2){
  if(val%i==0)return false;
  }
  return true;
}
</script>

<form>
<input type="text" name="tal">
<button onclick="alert((primtalscheck(this.form.tal.value))?'Det er et primtal':'Det er ikke et primtal')">Check tal</button>
</form>
Avatar billede roenving Novice
14. februar 2004 - 18:02 #2
Da primtal over 2 kun kan være ulige udelukker vi lige de lige tal først, og så bruger jeg generelt modulus-funktionen, som returnerer resten ved en division ...

Da en test for primtal kun behøver at gå til kvadratroden af tallet, tester jeg ikke længere end dertil !-)
Avatar billede mikoalngelo Nybegynder
14. februar 2004 - 18:03 #3
Tusind tak for det.

Kan du forklare mig hvordan/hvorfor den virker (jeg er nemlig ikke særligt meget inde i den form for matematik (endnu))?

Smid et svar.
Avatar billede roenving Novice
14. februar 2004 - 18:04 #4
-- og så var der en fejl, i denne linje:

for(i=3;Math.floor(Math.sqrt(val))>=i;i+=2){
Avatar billede roenving Novice
14. februar 2004 - 18:04 #5
Velbekomme '-)
Avatar billede mikoalngelo Nybegynder
14. februar 2004 - 18:14 #6
Jeg skulle også lige til at brokke mig, for 25 og 35 er da ikke primtal.

Tak for det.

PS: Ved du så hvem der kan forklare mig hvordan/hvorfor den virker?
Avatar billede roenving Novice
14. februar 2004 - 18:29 #7
Et primtal er et tal hvor kun 1 og tallet selv går op i, så det, som skal checkes er, om der findes et tal større end 1 og mindre end tallet, som går op i det uden rest !-)

Da dette tal selvfølgelig skal have et andet tal (som også skal være forskellig fra 1 og tallet selv !-) at blive ganget med (evt. det samme) for at blive tallet, er det kun nødvendigt at checke til _og med_ kvadratroden ...

Eksempel, når vi skal teste 23 udelukker vi først at det er lige, for alle lige tal undtaget 2 er ikke primtal (i hvert fald 2 går op i det !-)

Derefter testes med 3, som giver resten 2 i heltalsdivision (23 modulus 3 er 2), så prøver vi med 5, men da 5 op i 23 er mindre end 5 er der ingen grund til at teste, for vi har udelukket alle muligheder under 5, så 5 vil ikke have et tal at blive ganget med for at give 23 !-)

Tilsvarende med f.eks. 53, som testes med 3 (rest 2), 5 (rest 3), 7 (rest 4) og så ikke mere, for hvis 9 skulle gå op i 53 skulle det ganges med et tal mindre end 9, og dem har vi allerede udelukket !-)

-- det giver selvfølgelig en masse overflødige tests, for at dividere med 9 er overflødigt, for så har vi jo allerede udelukket 3, som også går op i 9, så den ville have fanget den ...

-- men i praksis er den faktisk hurtigere, når vi snakker om de første 100-200 cifre, tror jeg det er !-)
Avatar billede mikoalngelo Nybegynder
14. februar 2004 - 18:49 #8
Kan du så lave et program/script, der er hurtigere EFTER de 100-200 cifre? (Ja, det er en udfordring... :)
Avatar billede roenving Novice
14. februar 2004 - 19:03 #9
Hvis du bare skal teste et enkelt tal, tror jeg endda det er meget mere, men ellers er taktikken, at man opbygger en database over de primtal, man har fundet ...
Avatar billede mikoalngelo Nybegynder
14. februar 2004 - 20:38 #10
Prøv lige det her...

<script type="text/javascript">
function primtalscheck(val){
val = +val;
if(val%2==0)return false;
for(i=3;Math.floor(Math.sqrt(val))>=i;i+=2){
  if(val%i==0)return false;
  }
  return true;
}
for (a = 0; a < 100; a++)
document.write(primtalscheck(parseFloat("1,11111111111111111111111111111111111111111111111111111111111111111111111e308")+a));
</script>
Avatar billede roenving Novice
15. februar 2004 - 03:44 #11
-- nu ved jeg ikke hvilken implementation af javascript du bruger, med en jeg bruger er kun nøjagtig på ca 15 cifre, så der er en begrænsning !-)
Avatar billede roenving Novice
15. februar 2004 - 05:05 #12
Du kan jo prøve denne maskine og se hvad den giver på et minut *g*

<script type="text/javascript">
var ok=stop=false,data=[2,3,5],tal=5,tid=0;
function primtal(){
var ny=true,nytid=new Date().getTime();
while((data.length%100)!=0||ny){
  tal+=2,ok=true;
  for(i=0;Math.floor(Math.sqrt(tal))>=data[i];i++){
    if(tal%data[i]==0)ok=false;
  }
  if(ok){
    data[data.length] = tal;
    ny=false;
  }
}
document.getElementById('tal').innerHTML = data.join(", ");
document.getElementById('antal').innerHTML = data.length;
tid += (new Date().getTime() - nytid);
document.getElementById('tid').innerHTML = tid;
if(!stop)setTimeout('primtal()',1000);
}
</script>

<body onload="primtal();">
<button onclick="stop=true">Stop beregning</button>
<h1>Primtal </h1>(ialt fundne: <span id="antal"></span>&nbsp;- tid brugt: <span id="tid"></span>&nbsp;ms.)
<div id="tal" style="font-family:tahoma,verdana,arial,sans-serif;font-size:x-small;">2</div>
</body>
Avatar billede roenving Novice
15. februar 2004 - 05:39 #13
Hos mig fandt den:
(ialt fundne: 24500 - tid brugt: 60404 ms.) -- sat til at stoppe, når den havde brugt et minut !-)

Sidste primtal var 280817
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:18 #14
En simpel optimering vi være kun at udregne kvadratroden een gang, og putte
den i en variabel. I en for-løkke i JavaScript (og Java, og C, og C++) udregnes
stopbetingelsen hver gang.

Primtal til kryptografisk brug skal være enormt meget større end disse, og kan
ikke findes eller checkes ved en simpel division som denne.
Avatar billede roenving Novice
15. februar 2004 - 06:24 #15
Kryptografisk bruges i dag minimum 1024 binære cifre, eller ?-)
Avatar billede roenving Novice
15. februar 2004 - 06:25 #16
-- og på en times arbejde fandet den:
(ialt fundne: 258700 - tid brugt: 3602057 ms.)
sidste primtal: 3628967
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:29 #17
Det er i den størrelsesorden, men i hvert fald over den 100 decimale cifre.

Du kan gøre mere ved hastigheden: Sørg for at tage modulus med 2, og derefter
kun med ulige tal, dvs: i=i+2  i for-løkken.
Avatar billede roenving Novice
15. februar 2004 - 06:30 #18
-- og med eriks optimering blev det på et minut:

(ialt fundne: 33600 - tid brugt: 60206 ms.) sidst fundne: 396637
Avatar billede roenving Novice
15. februar 2004 - 06:31 #19
>>erik, den har jeg jo med *lol*
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:31 #20
Og endnu mere: stop da forløkken så snart en divisor er fundet, dvs. når ok=true.
De fleste tal er ikke primtal. Eller du kan nøjes med at dividere med de
kendte primtal, som du allerede har i et array.
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:32 #21
Du tester kun ulige tal, men dividerer med lige tal - overflødigt! ;)
Avatar billede roenving Novice
15. februar 2004 - 06:33 #22
Lige den sidste er jo et svar på den optimering, som skal bruges med meget store tal, så den dividerer kun med indholdet af arrayet ...

-- og det indeholder kun primtal !-)
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:35 #23
Nå ja, du dividerer også kun med primtallene! Så kan det ikke blive bedre.
Men det er stadigvik ikke på nogen måde anvendeligt på primtal af kryptografisk
størrelse.
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:39 #24
Hvilke tal får du med:

while((data.length%100)!=0||ny){
  tal+=2,ok=true;
  s=Math.floor(Math.sqrt(tal));
  for(i=0;s>=data[i]&&ok;i++){
    if(tal%data[i]==0)ok=false;
  }
  if(ok){
    data[data.length] = tal;
    ny=false;
  }
}
Avatar billede roenving Novice
15. februar 2004 - 06:45 #25
Med break; på et minut: ialt fundne: 45800 - sidste: 556441

Og når den selv fik lov til at køre derudaf:

ialt fundne: 84816 -- sidste: 1087631
Avatar billede roenving Novice
15. februar 2004 - 06:47 #26
Må jeg lige prøve ...

-- s-parameteren er brugt i de sidste mange, men ideen med at sætte ok som betingelse har jeg ikke prøvet, jeg har brugt en break i stedet !-)
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:48 #27
Og det er lidt bedre, ikke? ;))
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 06:49 #28
Break er også fint nok set fra et effektivitetsmæssigt hensyn, og nok også lidt
hurtigere.

Ukontrollable stopkriterier i løkker kan dog nedsætte læseligheden....
Avatar billede roenving Novice
15. februar 2004 - 06:51 #29
-- jeg skulle også kigge tre gange på &&ok før jeg fattede den *g*
Avatar billede roenving Novice
15. februar 2004 - 07:01 #30
&&ok var en anelse langsommere en break;

-- den gav kun 80578 fundne !-)
Avatar billede roenving Novice
15. februar 2004 - 07:08 #31
-- og så er det godt nok svært at sammenligne med det jeg oplevede, da jeg for 17 år siden fik mulighed for at sætte en basic-rutine til at checke tips-systemer med 9 tegn på en sprit-ny 33 Mhz-maskine ...

for de 3^11 muligheder (177147) tog mange dage !-)
Avatar billede roenving Novice
15. februar 2004 - 07:15 #32
-- med lige en anelse opmærksomhed på andre processer gav den så 83290 primtal ...

-- hvis jeg nu lukkede de 10 andre programmer kan det være, at den giver lidt mere, men break er åbenbart en anelse bedre end &&ok !-)
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 07:17 #33
Skriv den i C, så skal du bare se.

Lidt poesi en søndag morgen ;)
Avatar billede roenving Novice
15. februar 2004 - 07:23 #34
*lol*

-- og når det var den eneste proces (IE i JS) gav den 87045 med &&ok ...

-- og i c++ giver den vel nærmest en fordobling af effektiviteten, og i assembler kunne man vel lave en rutine, som for alvor udnyttede prefetchen i pIII-processoren !-)
Avatar billede erikjacobsen Ekspert
15. februar 2004 - 08:09 #35
Ja ja, men disse små optimeringer vil stadig ikke komme i
nærheden af kryptografiske primtal. Men det er jo slet ikke
sikkert spørgeren er interesseret i det ;)
Avatar billede roenving Novice
15. februar 2004 - 08:51 #36
Næh ...
Avatar billede mikoalngelo Nybegynder
16. februar 2004 - 19:29 #37
1) Jeg kan OVERHOVEDET ikke følge med i alt det i snakker om.
2) Jo, jeg er interresseret i et kryptografisk primtal, bare for at se hvordan sådan et ser ud.
3) Hvordan ville du skrive et program, erikjacobsen, der ville kunne TJEKKE et kryptografisk primtal, f.eks et på 300 cifre, ca.?
Avatar billede mikoalngelo Nybegynder
16. februar 2004 - 19:31 #38
Kan en af jer ikke skrive en artikel om primtals-generatorer og -tjekkere her på E. Den ville nok blive populær, og i hvert fald 5 p. værd, hvis det er på det niveau, i har snakket her... (Og nej, det er ikke for at fedte, det er oprigtigt ment!)
Avatar billede erikjacobsen Ekspert
16. februar 2004 - 19:31 #39
3) det ville jeg slet ikke gøre. Jeg ville konstruere et tilfældigt primtal af
passende størrelse ved hjælp af avancerede matematiske metoder.
Avatar billede mikoalngelo Nybegynder
16. februar 2004 - 19:33 #40
Og hvilke ville det være. Jeg er HELT VILDT interresseret i matematik, og jeg ville sikkert kunne imponere min matematiklærer, hvis jeg lige diskede op med sådan en logaritmisk funktion...
Avatar billede erikjacobsen Ekspert
16. februar 2004 - 19:45 #41
Ja, tak, det ligger nok lidt over dit niveau :)
Avatar billede mikoalngelo Nybegynder
16. februar 2004 - 20:03 #42
Er det fordi du ikke KAN lave den, eller fordi du ikke vil, eller hvad ;)
Avatar billede mikoalngelo Nybegynder
16. februar 2004 - 20:04 #43
Jeg er desværre nødt til at gå offline til i morgen. Vi ses der. Bare snak videre.
Avatar billede erikjacobsen Ekspert
16. februar 2004 - 20:22 #44
Jeg har skam lært på universitet hvordan man principielt gør.
Derfor ved jeg også det er over dit niveau. Og jeg gider ikke
finde et program til dig, som du alligevel ikke forstår hvordan
virker.
Avatar billede mikoalngelo Nybegynder
26. februar 2004 - 20:21 #45
Ærgeligt. Men man har jo dog ikke en morfar der er pensioneret overlærer i fysik-kemi og elektronik, og en mormor der er persioneret overlærer i matematik, dansk og tysk for ingenting, trods alt.
Nå, men pyt nu med det...

PS: Men computer har været nede MEGA længe, det er derfor jeg ikke har skrevet... Sory (Ja, med et r).
Avatar billede hcs89 Nybegynder
04. november 2008 - 17:46 #46
Er det ikke meget besværligt bare for at finde primtal? ...dether virker:
<script type="text/javascript">

//start- og slut-værdier:
var i=1
var max=100

//overskrift:
document.write("<b>Tal mellem 1 og "+max+":</b><br>")

for (i=i;i<=max;i=i+1)
{
prim="ja"
    for (n=2;n<i;n=n+1)
    {
        if (i%n==0)
        {
        //Denne linie kan tages med hvis man vil have en komplet liste
        // document.write(i+" er ikke et primtal.<br>")
        prim="nej"
        break;
        }
    }
if (prim=="ja")
{
document.write("<i>"+i+" er et primtal</i><br>")
}
}
</script>
Avatar billede erikjacobsen Ekspert
04. november 2008 - 17:49 #47
Den er fin til at finde bittesmå primtal.
Avatar billede hcs89 Nybegynder
04. november 2008 - 18:59 #48
hm.. ja det har du ret i. den begynder at blive langsom når man kommer over 1.000.000
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester