Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] Mnozenie tablic
Forum PHP.pl > Forum > Przedszkole
Wolfie
Witam,


Chce pomnozyc wszystkie elementy tablicy przez same siebie, tzn pierwszy element * drugi * trzeci * czwarty itd

No i napisalem taki kod :

  1. for($i = 0; $i < $key; $i++) {
  2. $spamprob_arr[$i] = $spamcount[$i]/$totspam;
  3. $hamprob_arr[$i] = $hamcount[$i]/$totham;
  4. //$totalprob[$i] = $spamprob[$i]/($spamprob[$i]+$hamprob[$i]);
  5. $spamprob = $spamprob_arr[$i] * $spamprob_arr[$i+1];
  6. }


Ale dostaje taki error :

Cytat
Notice: Undefined offset: 1 in C:\Apache\htdocs\PrackaMgr\class.Filter.php on line 79


I tak dla wszystkich elementow tablicy, rozumiem ze blad jest w ostatniej linijce w [$i+1] ale nie wiem jak pomnozyc elementy tablicy przez sama siebie ze sie tak wyraze...
Fifi209
  1. for ($i=0, $y=1; $i < $key; $i++, $y++) {
  2. $spamprob_arr[$i] = $spamcount[$i]/$totspam;
  3. $hamprob_arr[$i] = $hamcount[$i]/$totham;
  4. //$totalprob[$i] = $spamprob[$i]/($spamprob[$i]+$hamprob[$i]);
  5. $spamprob = $spamprob_arr[$i] * $spamprob_arr[$y];
  6. }
Wolfie
No niestety fifi, ten sam blad caly czas.....
Suh
array_product()
Wolfie
Ok Suh, swietna funkcja, ale chcialbym wiedziec jak to dziala bez takich dodatkow, chce sie nauczyc programowac a nie korzystac z funkcji bo to juz mniej wiecej umiem winksmiley.jpg
#luq
  1. $array = array( 1, 4, 5 );
  2.  
  3. $product = 1;
  4. foreach( $array as $k => $v ){
  5. $product *= $v;
  6. }


edit
Aha, a błąd polega na tym że musiałbyś napisać tak
  1. $spamprob_arr[ ($i+1) ]
Wolfie
Poza tym bardzo dziwna spraw, bo uzywajac array_product() wynik wychodzi mi 0, a wiem ze tablica nie jest pusta bankowo :


Oto wartosci z tablicy :

Cytat
Array ( [0] => 0.0034924330616997
[1] => 0.010477299185099
[2] => 0.025611175785797
[3] => 0.017462165308498
[4] => 0.013969732246799
[5] => 0.034924330616997
[6] => 0.015133876600698
[7] => 0.039580908032596
[8] => 0.011641443538999
[9] => 0.0058207217694994
itd....


#luq troche tego nie rozumiem ,dlaczego zmienna $product jest inicjalizowana wartoscia 1 ?

----------------------------------------------

Piszac :

  1. $spamprob_arr[($i+1)];


Caly czas ten sam blad :

Cytat
Notice: Undefined offset: 1 in C:\Apache\htdocs\PrackaMgr\class.Filter.php on line 79

Suh
Cytat(Wolfie @ 21.08.2009, 16:45:25 ) *
#luk troche tego nie rozumiem ,dlaczego zmienna $product jest inicjowana wartoscia 1 ?


Bo w PHP wszystkie zmienne domyślnie są INICJALIZOWANE (nie inicjowane.. inicjacja to może być ale inna winksmiley.jpg ) wartością 0 lub inną odpowiednią do typu zmiennej. A jak dobrze wiesz mnożenie przez 0 daje 0.

PS. Testowałem funkcję array_product dla tablicy którą pokazałeś i wyszedł mi wynik różny od zera... chociaż bardzo zbliżony (3.240715006464E-19 dla pierwszych 10 elementów).

PS2.
A błąd Ci wywala z prostego powodu. Nie sprawdzasz czy element $i+1 znajduje się w zakresie tablicy. Stąd też ten offset. Próbujesz się dostać np. do 11 elementu 10-elementowej tablicy.
#luq
Cytat(Wolfie @ 21.08.2009, 16:45:25 ) *
#luk

luq sleep.gif
Wolfie
To moze wyszlo 0 dlatego ze zmienna jest typu int ? Musze przekonwertowac zmienna na typ zmiennoprzecinkowy ?

ups....sorry juz poprawilem nick winksmiley.jpg
l0ud
Może przy większej ilości elementów typu 0.01... brakuje miejsc po przecinku i w którymś momencie po prostu zaokrągla do 0?
Wolfie
-------------------------------------------------

No nie wiem jak Ty to robisz , ja robie to tak :

  1. $spamprob = array_product($spamprob_arr);
  2. print_r($spamprob);



I ewidentnie wynik jest "0".....

-------------------------------------------------

Probowalem tak :

  1. $spamprob = array_product($spamprob_arr);
  2. $float_spamprob = (float)$spamprob;


I wynik ciagle 0......
zegarek84
a jak dużą masz tą tablicę - z ilu elementów?? i czy wszystkie elementy są z przedziału -1<=x<=1?? jeśli tak to przy każdym mnożeniu przy liczbie elementów dążącej do +nieskończoności (dużej liczby elementów) granica z wyniku zbliża się do 0±
a poza tym sprawdź czy któryś element faktycznie nie jest równy 0
Suh
Sprawdź sobie jak wygląda Twoja tablica $spamprob_arr, czy nie ma tam gdzieś zera ?
Wolfie
Tablica ma duzo elementow 175, ale bede musial przez ta funkcje przepuszczac rowniez tablice znacznie wieksze,

Sprawdzilem , nie ma tam zadnego 0, sa bardzo male liczby, zazwyczej z dwoma zerami po przecinku, ale 0 nigdzie nie ma, ale faktycznie jak iteruje tylko po 10 elementach to wychodzi normalnie wynik, jak lece po wszystkich to wychodzi 0.........

-------------------------------------------------

Jak przekraczam liczbe 157 elementow po ktorych interuje tablice pojawia sie w wyniku 0, choc 157-my element tablicy, ani zaden dalej nie jest rowny 0......no i co teraz proponujecie Panowie ?
Suh
Szczerze to już chyba nic nie zrobisz z tym.. liczba jest już tak mała że jest uznawana za 0.
Poczytaj sobie o tym w manualu.
http://pl.php.net/manual/pl/language.types.float.php
zegarek84
więc wychodzisz poza zakres pamięci i 175 liczb z 2 zerami po przecinku daje jakąś liczbę mniejszą od 1×10^(-350) - a więc w zasadzie 0...

jeśli potrzebujesz tak dokładnych obliczeń musisz zrobić jakąś pamięć np. jako ciąg tekstowy i na nim operować - raz na forum zamieszczałem funkcję do obliczania silni z dużych liczb - przy dużej tablicy obliczenia trochu mogą potrwać gdyż będziesz je musiał porcjować i operować na ciągu tekstowym - innego pomysłu nie mam...

[edit]
do wymyślenia algorytmu powinno Ci wystarczyć w zasadzie zapamiętanie potęgi 10^X - czyli tego X i zara poszukam posta z tamtą silnią to sobie algorytm przerobisz - liczby po prostu przekształcisz na całkowite a osobno jeszcze pamięć tego X....
Wolfie
A czy jakies zaokraglenie liczb przed pomnozeniem ich przez siebie cos da ?

Bo tak mi sie wydaje ze poprostu liczba ma tak duzo miejsc po przecinku ze juz komputer tego nie ogarnia winksmiley.jpg blink.gif

Nie no , nie potrzebuje liczb z tyloma miejscami po przecinku, wystarczy powiedzmy 5 liczb po przecinku i powinno byc ok, jak najlepiej w takim razie te liczby skrocic ?
Suh
Komputer to ogarnia.. niech Cie już o to głowa nie boli winksmiley.jpg
A co do zaokrąglania to marny pomysł trochę.. ze względu na to, że Twoje liczby są małe i nawet gdybyś chciał to zaokrąglać powiedzmy do części tysięcznej to mimo to może się trafić jakaś liczba która zostanie zaokrąglona do zera.
rzymek01
jesli zależy ci na precyzji poczytaj o bibliotece bcmath smile.gif

na pewno masz wszystkie indeksy wypełnione liczbą <> 0 w tablicy $spamprob_arr ?
Wolfie
No fakt, to niezly kanal jednym slowem.......a mialo byc tak pieknie sciana.gif

To moze pokaz ten algorytmik o ktorym wspominales, w zasadzie nie wiem o czym mowiles tak naprawde ale jak bedzie trzeba to ogarne kwestie.....
zegarek84
Cytat(Suh @ 21.08.2009, 17:19:52 ) *
Komputer to ogarnia.. niech Cie już o to głowa nie boli winksmiley.jpg
A co do zaokrąglania to marny pomysł trochę.. ze względu na to, że Twoje liczby są małe i nawet gdybyś chciał to zaokrąglać powiedzmy do części tysięcznej to mimo to może się trafić jakaś liczba która zostanie zaokrąglona do zera.

w pierwszym zdaniu podałem Ci ile zer po przecinku będziesz miał mnożąc te 175 cyfr ;p - a skoro wystarcza Ci 5 miejsc po przecinku to wynik masz prawidłowy bo równy 0 ;p ^^

możesz wynik zapisać tak jak na kalkulatorze dla przykładu 123456×10^[-40] co jest czytelne - ale jeśli nie chcesz to za Ciebie nikt gotowca nie napisze ;p

ale jakbyś chciał to przeanalizuj to i jak tu problem był rozwiązany:
http://forum.php.pl/index.php?showtopic=11...mp;#entry581527
masz tam przedstawioną drogę którą musisz podążać - ale nie jest to gotowe rozwiązanie....
Wolfie
--------------------------------------------------
rzymek01 tak, bankowo wszystkie liczby sa != od zera......

zegarek84
Najwiekszy problem to taki ze ja bede mial w tych tablicach nawet po 1000 albo i wiecej takich wartosci, 175 to pikus dla testowania smile.gif
Jedyny plus to taki ze dobrze ze to teraz wyszlo a nie w pozniejszej fazie ...... smile.gif
zegarek84
no i przy wyniku z przykładowym zapisem wynik będzie dokładny i czytelny winksmiley.jpg 123456×10^[-4000] - ale musisz dostosować rozwiązanie do wymogów - tam nie ma gotowca co podałem link ale jest droga jaką powinieneś obrać winksmiley.jpg
Wolfie
zegarek84
Robie projekt ale czas nie pozwala mi teraz skupiac sie na takich rozwiazaniach jak mi podales, a biblioteka BCMath nie wystarczy ?
zegarek84
sprawdź - z tego rozwiązania akurat ja nie korzystałem winksmiley.jpg - tak więc możesz sprawdzić...
[edit]
tutaj jest przykład użycia:http://pl.wikipedia.org/wiki/BCMath

[edit]
ale przy 1000 liczbach gdzie każda ma co najmniej 2 zera po przecinku precyzję musisz ustawić znacznie ponad 2000 aż winksmiley.jpg
Wolfie
No i komu teraz wstawic "pomogl" ? laugh.gif

Kurcze sam nie wiem, przejrzalem to BCMath ale tam jest funkcja tylko do mnozenia dwoch liczb o duzej dokladnosci a nie calej tablicy.....
zegarek84
no to zrób funkcję z 2 wejściowymi zmiennymi - jedna zmienna niech będzie z referencją na wejściu a druga jako kolejny element tablicy wstawiana w tej pętli - tzn przechodząc w pętli tablicę za każdym razem wywołuj tą funkcję w której masz to BCMath - ale wydaje mi się że przy tak dużej precyzji to obliczenia mogą nie być najszybsze i może się okazać szybszy dobrze napisany algorytm na tekście - ale to co mi się wydaje a co będzie to mogą być 2 różne sprawy - po prostu trzeba spróbować i najwyżej porównać czas obliczeń winksmiley.jpg

// edit

lub odpowiednio skonstruuj pętlę z wykorzystaniem tego BCMath bez funkcji dodatkowych i referencji ;p
erix
array_walk użyć nie możesz...?
l0ud
No to użyj tego bcmul w pętli, z wszystkimi elementami tablicy, zaczynając od jedynki. (czyli 1 * pierwszy * drugi * trzeci....)
Wolfie
Tzn wygladaloby to mniej wiecej tak :

  1. for($i = 0; $i < $key; $i++) {
  2. $spamprob_arr[$i] = $spamcount[$i]/$totspam;
  3. $hamprob_arr[$i] = $hamcount[$i]/$totham;
  4. bcmul( $spamprob_arr[$i] , $spamprob_arr[($i+1)];)
  5. }


Cytat
jedna zmienna niech będzie z referencją na wejściu a druga jako kolejny element tablicy wstawiana w tej pętli


Sorry ale nigdy jeszcze nie uzywalem referencji, mozesz jakis przyklad zapodac ?

Cytat
array_walk użyć nie możesz...?


rozumiem ze mowisz zebym uzyl funkcji array_walk wewnatrz bcmul......?

------------------------------------------------------------

Dziekuje wszystkim za pomoc, to byla pouczajaca dyskusja yahoo.gif
erix
Cytat
rozumiem ze mowisz zebym uzyl funkcji array_walk wewnatrz bcmul......?

Nie, osobna funkcja do tego, z wykorzystaniem trzeciego parametru array_walk jako referencji.

Co to jest? Poczytaj. Ale w olbrzymim skrócie, jest to jakby przekazanie uchwytu do obiektu/zmiennej zamiast jej kopiowania.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.