12
votes

Les numéros d'échelle doivent être <= 255?

J'ai des cellules pour lesquelles la valeur numérique peut être quelque chose entre 0 et INTEGER.MAX_VALUE . Je voudrais colorier le code de ces cellules en conséquence.

si la valeur = 0, alors r = 0. Si la valeur est integer.max_value , puis r = 255. Mais qu'en est-il des valeurs entre les deux?

Je pense que j'ai besoin d'une fonction dont la limite comme x => integer.max_value est 255. Quelle est cette fonction? Ou y a-t-il une meilleure façon de le faire?

Je pourrais juste faire (valeur / (intger.max_value / 255)) mais cela entraînera de nombreuses valeurs de faible valeur. Donc, peut-être que je devrais le faire avec une fonction de journalisation.

La plupart de mes valeurs seront comprises entre [0, 10 000]. Donc, je veux mettre en évidence les différences là-bas.


4 commentaires

Je ne sais pas pourquoi le vote de fermer. Cela me semble une vraie (et une bonne) question pour moi.


Comment cela peut-il être étiqueté Java et langue-agnostique?


Je pense que vous pouvez l'étiqueter comme les deux car il peut y avoir une solution générale (meilleure) et une java-spécifique une (meilleure)


C'est une langue agnostique, car il y a une solution générale, mais la langue que je travaille est en train de travailler est Java.


13 Réponses :


-1
votes

Je pourrais juste faire (valeur / (integer.max_value / 255)) mais cela entraînera de nombreuses valeurs bases.

Une approche que vous pourriez prendre est d'utiliser l'opérateur modulo ( r = valeur% 256; ). Bien que cela ne garantirait pas que INTEGER.MAX_VALUE s'avère 255, Il garantirait un nombre entre 0 et 255. Cela permettrait également de distribuer des nombres faibles à travers la gamme 0-255.

EDIT:

Funnily, comme je teste cela, integer.max_value% 256 aboutit à 255 (j'ai été testé à l'origine par erreur contre % 255 , qui a donné les mauvais résultats). Cela semble être une solution assez simple.


2 commentaires

Ce n'est pas explicitement énoncé, mais il semble implicicit dans la question que les couleurs devraient collecter des valeurs similaires - c'est-à-dire que deux cellules partagent une couleur, leur valeur sera à peu près équivalente. Dans votre réponse, la couleur n'a pas de rapport avec l'ampleur de la valeur.


Kirk, je conviens que l'idée de distribution dans des seaux de valeurs similaires était une idée . Il semble également que l'OP était ouvert à d'autres solutions. Il semble toutefois que la plupart des intervenants ont pris le regroupement de valeurs similaires comme la seule solution.



1
votes

La valeur que vous recherchez est: R = 255 * (valeur / integer.max_value). Donc, vous devriez transformer cela en un double, puis jeté à un int.


4 commentaires

Ugh, tu as raison, j'ai tapé ça trop vite. Vous auriez pu spécifier la correction, mais j'ai pris votre indice subtil et a couru avec elle.


@Artelius: oui vous pouvez. Cliquez à nouveau sur le vote de descente (pas sur la flèche UP-VOTE)


J'ai édité le message, vous devriez maintenant pouvoir inverser votre vote.


Lol c'est bon, c'est ce que je reçois pour cliquer sur Ajouter un commentaire sans lire ce que j'ai saisi.



2
votes

En général (puisqu'il n'est pas clair pour moi s'il s'agit d'une question Java ou langue-agnostique), vous diviseriez la valeur que vous avez par integer.max_value , multiplie par 255 et convertir en un entier.


4 commentaires

La seule façon de le faire est de se lancer dans un double à un moment donné, il est plus efficace de le faire dans l'inverse.


@Erich, mais alors vous avez une chance de débordement.


Vous ne déboucherez pas si vous divisez en premier!


C'est ce que j'ai fait. Qu'entendez-vous par «faire l'inverse»?



2
votes

Cela fonctionne! r = valeur / 8421504;

8421504 est en fait le chiffre 'magique', ce qui équivaut à MAX_VALUE / 255. Ainsi, max_value / 8421504 = 255 (et certains changements, mais suffisamment d'entier entier se débarrasseront de cela.

si vous voulez un qui ne comportent pas de numéro magique en elle, cela devrait fonctionner (et de performance égale, car tout bon compilateur remplacer par la valeur réelle:

r = valeur / (integer.max_value / 255);

La belle partie est, cela ne nécessitera aucune valeur de point flottant.


1 commentaires

Comment? Les valeurs de 0-int.max seront distribuées uniformément à 0-255, n'est-ce pas?



16
votes

La mise à l'échelle linéaire "la plus juste" est réellement faite comme ceci:

255 * log(value + 1) / log(Integer.MAX_VALUE + 1)


4 commentaires

Cela fonctionne mieux quand il est journal (INTEGER.MAX_VALUE) au lieu de LOG (INTEGER.MAX_VALUE + 1) . Sinon, chaque résultat est 0 parce que journal (integer.max_value) est nan .


Peut-être que les critiques peuvent maintenant voir comment c'est la langue agnostique, même si le codeur travaille dans la seule vraie langue


@Rosarch: Bon point. J'aurais pu tester mon code avant de poster, mais pourquoi me briserais mon vœu de ne jamais utiliser Java sur quelque chose de si trivial? ;) Encore, en tant que programmeur C, j'aurais dû savoir mieux ...


Une déclaration que Java pourrait être interprétée de quelque manière que ce soit interprété comme une seule vraie langue doit être un appât de flamme intentionnel. Comment cela a-t-il été voté?



0
votes

La meilleure réponse dépend vraiment du comportement que vous voulez.

Si vous voulez que chaque cellule ait généralement une couleur différente du voisin, accédez à ce que AKF a dit dans le deuxième paragraphe et utilisez un modulo (x% 256).

Si vous voulez que la couleur ait une certaine importance sur la valeur réelle (comme "bleu signifie des valeurs plus petites" tout le chemin de "rouge signifie énormes valeurs"), vous devriez poster quelque chose sur votre répartition des valeurs attendue. Puisque vous vous inquiétez de nombreuses valeurs basses étant zéro, je pourrais deviner que vous en avez beaucoup, mais cela ne serait qu'une supposition.

Dans ce deuxième scénario, vous souhaitez vraiment distribuer vos réponses probables en 256 "pour centiles" et attribuer une couleur à chacun (où un nombre égal de réponses probables tombe dans chaque centile).


0 commentaires

3
votes

Pour une cartographie linéaire de la plage 0-2 ^ 32 à 0-255, prenez simplement l'octet haute commande. Voici comment cela ressemblerait à l'aide d'utiliser binaire & et bit-shifting: xxx

à l'aide du mod 256 retournera certainement une valeur 0-255, mais vous ne serez pas capable de Dessinez tout sens du regroupement des résultats - 1, 257, 513, 1025 de la valeur échelle 1, même s'ils sont loin les uns des autres.

Si vous voulez être plus discriminant parmi les basses valeurs et fusionner de nombreuses valeurs de grande taille ensemble, une expression de journal fonctionnera: xxx

edit : yikes, mon professeur d'algèbre de lycée Mme Buckenmeyer serait faible! LOG (POW (2,32)) est identique à celui de 32 * journal (2) , et beaucoup moins cher à évaluer. Et maintenant, nous pouvons également prendre en compte cela mieux, car 256/32 est un bon nombre de 8: xxx

journal (valeur) / journal (2) est en fait log-base-2 de la valeur , quel journal fait pour nous très proprement: xxx

là, Mme Buckenmeyer - vos efforts Weren ' t entièrement gaspillé!


1 commentaires

Ooops, désolé, j'ai glissé dans Python là-bas. java.math.log ne prend pas un deuxième arg. Vous êtes donc bloqué avec le journal (valeur) / Journal (2).



0
votes

Si vous vous plaintenez que les numéros bas deviennent zéro, vous voudrez peut-être normaliser les valeurs à 255 plutôt que toute la plage de valeurs.

La formule deviendrait:

CurrentValue / (valeur max de l'ensemble)


0 commentaires

1
votes

Notez que si vous voulez plus brillant et plus lumineux, cette luminosité n'est pas linéaire, une cartographie droite de la valeur à la couleur ne donnera pas un bon résultat.

La classe de couleur a une méthode pour faire une couleur plus lumineuse. Regardez cela.


0 commentaires

1
votes

La mise en œuvre linéaire est discutée dans la plupart de ces réponses et la réponse d'Artelius semble être la meilleure. Mais la meilleure formule dépendrait de ce que vous essayez d'atteindre et de la distribution de vos valeurs. Sans savoir qu'il est difficile de donner une réponse idéale.

Mais juste pour illustrer, tout d'entre eux pourrait être le meilleur pour vous:

  • Distribution linéaire, chaque mappage sur une plage de 1/266ème de la plage globale.
  • Distribution logarithmique (asymétrique vers des valeurs faibles) qui mettra en évidence les différences dans les grandeurs inférieures et diminuer les différences dans les magnitudes plus élevées
  • Distribution logarithmique inverse (asymétrique vers des valeurs élevées) qui mettra en évidence les différences entre les grandeurs plus élevées et diminuer les différences dans les grandeurs inférieures.
  • Répartition normale de l'incidence des couleurs, où chaque couleur apparaît le même nombre de fois que toutes les autres couleurs.

    Encore une fois, vous devez déterminer ce que vous essayez d'atteindre et de ce que les données seront utilisées pour. Si vous avez été chargé de construire cela, je vous recommande vivement de l'obtenir clarifié pour vous assurer que cela est aussi utile que possible - et d'éviter d'avoir à le réaménager plus tard.


0 commentaires

1
votes

Demandez-vous à la question "Quelle valeur devait mapper sur 128?" Si la réponse est d'environ un milliard (je doute que cela soit), utilisez ensuite linéaire. Si la réponse est comprise entre 10-100 000, considérez la racine carrée ou le journal.

Une autre réponse suggérée ceci (je ne peux pas encore commenter ni voter). Je suis d'accord.

r = journal (valeur) / journal (POW (2,32)) * 256


0 commentaires

5
votes

J'ai pensé qu'un logement de journal serait bon pour cela, mais je regarde les résultats, je ne suis pas si sûr.

Cependant, Wolfram | Alpha est idéal pour Expérimentation avec ce genre de chose :

J'ai commencé avec cela, et fini par: xxx

intéressant, il s'avère que cela donne des résultats presque identiques à la réponse d'Artelius de: xxx

IMHO, vous seriez mieux servis avec une fonction scindée pour 0-10000 et 10000-2 ^ 31.


2 commentaires

Après ma simplification algébrique ci-dessous, je pense que cela pourrait bien servir pour vous: r (x) = plancher ((256./31) * journal (x) / journal (2))


Yup, c'est certainement plus simple, bien que cela souffre toujours de la question d'un mauvais ajustement par rapport aux valeurs souhaitées.



1
votes

Voici un tas d'algorithmes pour la mise à l'échelle, la normalisation, le classement, etc. Numéros à l'aide de méthodes d'extension en C #, bien que vous puissiez les adapter à d'autres langues:

http://www.redowlconsulting.com/blog/ Post / 2011/07/28 / Statisticaltricksforlists.aspx

Il existe des explications et des graphiques qui expliquent lorsque vous voudrez peut-être utiliser une méthode ou une autre.


0 commentaires